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
23 #include "coretypes.h"
28 /* Nonzero iff an error has occurred. */
29 static int hit_error
= 0;
31 static void gen_rtx_next
PARAMS ((void));
32 static void write_rtx_next
PARAMS ((void));
33 static void open_base_files
PARAMS ((void));
34 static void close_output_files
PARAMS ((void));
36 /* Report an error at POS, printing MSG. */
39 error_at_line
VPARAMS ((struct fileloc
*pos
, const char *msg
, ...))
42 VA_FIXEDARG (ap
, struct fileloc
*, pos
);
43 VA_FIXEDARG (ap
, const char *, msg
);
45 fprintf (stderr
, "%s:%d: ", pos
->file
, pos
->line
);
46 vfprintf (stderr
, msg
, ap
);
53 /* vasprintf, but produces fatal message on out-of-memory. */
55 xvasprintf (result
, format
, args
)
60 int ret
= vasprintf (result
, format
, args
);
61 if (*result
== NULL
|| ret
< 0)
63 fputs ("gengtype: out of memory", stderr
);
69 /* Wrapper for xvasprintf. */
71 xasprintf
VPARAMS ((const char *format
, ...))
75 VA_FIXEDARG (ap
, const char *, format
);
76 xvasprintf (&result
, format
, ap
);
81 /* The one and only TYPE_STRING. */
83 struct type string_type
= {
84 TYPE_STRING
, NULL
, NULL
, GC_USED
88 /* Lists of various things. */
90 static pair_p typedefs
;
91 static type_p structures
;
92 static type_p param_structs
;
93 static pair_p variables
;
95 static void do_scalar_typedef
PARAMS ((const char *, struct fileloc
*));
96 static type_p find_param_structure
97 PARAMS ((type_p t
, type_p param
[NUM_PARAM
]));
98 static type_p adjust_field_tree_exp
PARAMS ((type_p t
, options_p opt
));
99 static type_p adjust_field_rtx_def
PARAMS ((type_p t
, options_p opt
));
101 /* Define S as a typedef to T at POS. */
104 do_typedef (s
, t
, pos
)
111 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
112 if (strcmp (p
->name
, s
) == 0)
116 error_at_line (pos
, "type `%s' previously defined", s
);
117 error_at_line (&p
->line
, "previously defined here");
122 p
= xmalloc (sizeof (struct pair
));
130 /* Define S as a typename of a scalar. */
133 do_scalar_typedef (s
, pos
)
137 do_typedef (s
, create_scalar_type (s
, strlen (s
)), pos
);
140 /* Return the type previously defined for S. Use POS to report errors. */
143 resolve_typedef (s
, pos
)
148 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
149 if (strcmp (p
->name
, s
) == 0)
151 error_at_line (pos
, "unidentified type `%s'", s
);
152 return create_scalar_type ("char", 4);
155 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
156 at POS with fields FIELDS and options O. */
159 new_structure (name
, isunion
, pos
, fields
, o
)
168 lang_bitmap bitmap
= get_base_file_bitmap (pos
->file
);
170 for (si
= structures
; si
!= NULL
; si
= si
->next
)
171 if (strcmp (name
, si
->u
.s
.tag
) == 0
172 && UNION_P (si
) == isunion
)
175 if (si
->kind
== TYPE_LANG_STRUCT
)
179 for (si
= ls
->u
.s
.lang_struct
; si
!= NULL
; si
= si
->next
)
180 if (si
->u
.s
.bitmap
== bitmap
)
183 else if (si
->u
.s
.line
.file
!= NULL
&& si
->u
.s
.bitmap
!= bitmap
)
186 si
= xcalloc (1, sizeof (struct type
));
187 memcpy (si
, ls
, sizeof (struct type
));
188 ls
->kind
= TYPE_LANG_STRUCT
;
189 ls
->u
.s
.lang_struct
= si
;
190 ls
->u
.s
.fields
= NULL
;
192 si
->pointer_to
= NULL
;
193 si
->u
.s
.lang_struct
= ls
;
198 if (ls
!= NULL
&& s
== NULL
)
200 s
= xcalloc (1, sizeof (struct type
));
201 s
->next
= ls
->u
.s
.lang_struct
;
202 ls
->u
.s
.lang_struct
= s
;
203 s
->u
.s
.lang_struct
= ls
;
210 s
= xcalloc (1, sizeof (struct type
));
211 s
->next
= structures
;
215 if (s
->u
.s
.line
.file
!= NULL
216 || (s
->u
.s
.lang_struct
&& (s
->u
.s
.lang_struct
->u
.s
.bitmap
& bitmap
)))
218 error_at_line (pos
, "duplicate structure definition");
219 error_at_line (&s
->u
.s
.line
, "previous definition here");
222 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
225 s
->u
.s
.fields
= fields
;
227 s
->u
.s
.bitmap
= bitmap
;
228 if (s
->u
.s
.lang_struct
)
229 s
->u
.s
.lang_struct
->u
.s
.bitmap
|= bitmap
;
232 /* Return the previously-defined structure with tag NAME (or a union
233 iff ISUNION is nonzero), or a new empty structure or union if none
234 was defined previously. */
237 find_structure (name
, isunion
)
243 for (s
= structures
; s
!= NULL
; s
= s
->next
)
244 if (strcmp (name
, s
->u
.s
.tag
) == 0
245 && UNION_P (s
) == isunion
)
248 s
= xcalloc (1, sizeof (struct type
));
249 s
->next
= structures
;
251 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
257 /* Return the previously-defined parameterized structure for structure
258 T and parameters PARAM, or a new parameterized empty structure or
259 union if none was defined previously. */
262 find_param_structure (t
, param
)
264 type_p param
[NUM_PARAM
];
268 for (res
= param_structs
; res
; res
= res
->next
)
269 if (res
->u
.param_struct
.stru
== t
270 && memcmp (res
->u
.param_struct
.param
, param
,
271 sizeof (type_p
) * NUM_PARAM
) == 0)
275 res
= xcalloc (1, sizeof (*res
));
276 res
->kind
= TYPE_PARAM_STRUCT
;
277 res
->next
= param_structs
;
279 res
->u
.param_struct
.stru
= t
;
280 memcpy (res
->u
.param_struct
.param
, param
, sizeof (type_p
) * NUM_PARAM
);
285 /* Return a scalar type with name NAME. */
288 create_scalar_type (name
, name_len
)
292 type_p r
= xcalloc (1, sizeof (struct type
));
293 r
->kind
= TYPE_SCALAR
;
294 r
->u
.sc
= xmemdup (name
, name_len
, name_len
+ 1);
298 /* Return a pointer to T. */
306 type_p r
= xcalloc (1, sizeof (struct type
));
307 r
->kind
= TYPE_POINTER
;
311 return t
->pointer_to
;
314 /* Return an array of length LEN. */
317 create_array (t
, len
)
323 v
= xcalloc (1, sizeof (*v
));
324 v
->kind
= TYPE_ARRAY
;
330 /* Add a variable named S of type T with options O defined at POS,
334 note_variable (s
, t
, o
, pos
)
341 n
= xmalloc (sizeof (*n
));
351 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
357 /* We really don't care how long a CONST_DOUBLE is. */
358 #define CONST_DOUBLE_FORMAT "ww"
359 static const char * const rtx_format
[NUM_RTX_CODE
] = {
360 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
365 static int rtx_next
[NUM_RTX_CODE
];
367 /* Generate the contents of the rtx_next array. This really doesn't belong
368 in gengtype at all, but it's needed for adjust_field_rtx_def. */
374 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
379 if (strncmp (rtx_format
[i
], "iuu", 3) == 0)
381 else if (i
== COND_EXEC
|| i
== SET
|| i
== EXPR_LIST
|| i
== INSN_LIST
)
384 for (k
= strlen (rtx_format
[i
]) - 1; k
>= 0; k
--)
385 if (rtx_format
[i
][k
] == 'e' || rtx_format
[i
][k
] == 'u')
390 /* Write out the contents of the rtx_next array. */
394 outf_p f
= get_output_file_with_visibility (NULL
);
397 oprintf (f
, "\n/* Used to implement the RTX_NEXT macro. */\n");
398 oprintf (f
, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
399 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
400 if (rtx_next
[i
] == -1)
401 oprintf (f
, " 0,\n");
404 " offsetof (struct rtx_def, fld) + %d * sizeof (rtunion),\n",
409 /* Handle `special("rtx_def")'. This is a special case for field
410 `fld' of struct rtx_def, which is an array of unions whose values
411 are based in a complex way on the type of RTL. */
414 adjust_field_rtx_def (t
, opt
)
416 options_p opt ATTRIBUTE_UNUSED
;
421 type_p rtx_tp
, rtvec_tp
, tree_tp
, mem_attrs_tp
, note_union_tp
, scalar_tp
;
422 type_p bitmap_tp
, basic_block_tp
;
424 static const char * const rtx_name
[NUM_RTX_CODE
] = {
425 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
430 if (t
->kind
!= TYPE_ARRAY
)
432 error_at_line (&lexer_line
,
433 "special `rtx_def' must be applied to an array");
437 nodot
= xmalloc (sizeof (*nodot
));
442 rtx_tp
= create_pointer (find_structure ("rtx_def", 0));
443 rtvec_tp
= create_pointer (find_structure ("rtvec_def", 0));
444 tree_tp
= create_pointer (find_structure ("tree_node", 1));
445 mem_attrs_tp
= create_pointer (find_structure ("mem_attrs", 0));
446 bitmap_tp
= create_pointer (find_structure ("bitmap_element_def", 0));
447 basic_block_tp
= create_pointer (find_structure ("basic_block_def", 0));
448 scalar_tp
= create_scalar_type ("rtunion scalar", 14);
451 pair_p note_flds
= NULL
;
454 for (c
= 0; c
< 3; c
++)
456 pair_p old_note_flds
= note_flds
;
458 note_flds
= xmalloc (sizeof (*note_flds
));
459 note_flds
->line
.file
= __FILE__
;
460 note_flds
->line
.line
= __LINE__
;
461 note_flds
->name
= "rttree";
462 note_flds
->type
= tree_tp
;
463 note_flds
->opt
= xmalloc (sizeof (*note_flds
->opt
));
464 note_flds
->opt
->next
= nodot
;
465 note_flds
->opt
->name
= "tag";
466 note_flds
->next
= old_note_flds
;
469 note_flds
->type
= rtx_tp
;
470 note_flds
->name
= "rtx";
471 note_flds
->opt
->info
= "NOTE_INSN_EXPECTED_VALUE";
472 note_flds
->next
->opt
->info
= "NOTE_INSN_BLOCK_BEG";
473 note_flds
->next
->next
->opt
->info
= "NOTE_INSN_BLOCK_END";
475 new_structure ("rtx_def_note_subunion", 1, &lexer_line
, note_flds
, NULL
);
478 note_union_tp
= find_structure ("rtx_def_note_subunion", 1);
480 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
482 pair_p old_flds
= flds
;
483 pair_p subfields
= NULL
;
484 size_t aindex
, nmindex
;
488 for (aindex
= 0; aindex
< strlen (rtx_format
[i
]); aindex
++)
490 pair_p old_subf
= subfields
;
494 switch (rtx_format
[i
][aindex
])
505 if (i
== MEM
&& aindex
== 1)
506 t
= mem_attrs_tp
, subname
= "rtmem";
507 else if (i
== JUMP_INSN
&& aindex
== 9)
508 t
= rtx_tp
, subname
= "rtx";
509 else if (i
== CODE_LABEL
&& aindex
== 4)
510 t
= scalar_tp
, subname
= "rtint";
511 else if (i
== CODE_LABEL
&& aindex
== 5)
512 t
= rtx_tp
, subname
= "rtx";
513 else if (i
== LABEL_REF
514 && (aindex
== 1 || aindex
== 2))
515 t
= rtx_tp
, subname
= "rtx";
516 else if (i
== NOTE
&& aindex
== 4)
517 t
= note_union_tp
, subname
= "";
518 else if (i
== NOTE
&& aindex
>= 7)
519 t
= scalar_tp
, subname
= "rtint";
520 else if (i
== ADDR_DIFF_VEC
&& aindex
== 4)
521 t
= scalar_tp
, subname
= "rtint";
522 else if (i
== VALUE
&& aindex
== 0)
523 t
= scalar_tp
, subname
= "rtint";
524 else if (i
== REG
&& aindex
== 1)
525 t
= scalar_tp
, subname
= "rtint";
526 else if (i
== SCRATCH
&& aindex
== 0)
527 t
= scalar_tp
, subname
= "rtint";
528 else if (i
== BARRIER
&& aindex
>= 3)
529 t
= scalar_tp
, subname
= "rtint";
532 error_at_line (&lexer_line
,
533 "rtx type `%s' has `0' in position %lu, can't handle",
534 rtx_name
[i
], (unsigned long) aindex
);
575 error_at_line (&lexer_line
,
576 "rtx type `%s' has `%c' in position %lu, can't handle",
577 rtx_name
[i
], rtx_format
[i
][aindex
],
578 (unsigned long)aindex
);
584 subfields
= xmalloc (sizeof (*subfields
));
585 subfields
->next
= old_subf
;
587 subfields
->name
= xasprintf ("[%lu].%s", (unsigned long)aindex
,
589 subfields
->line
.file
= __FILE__
;
590 subfields
->line
.line
= __LINE__
;
591 if (t
== note_union_tp
)
593 subfields
->opt
= xmalloc (sizeof (*subfields
->opt
));
594 subfields
->opt
->next
= nodot
;
595 subfields
->opt
->name
= "desc";
596 subfields
->opt
->info
= "NOTE_LINE_NUMBER (&%0)";
598 else if (t
== basic_block_tp
)
600 /* We don't presently GC basic block structures... */
601 subfields
->opt
= xmalloc (sizeof (*subfields
->opt
));
602 subfields
->opt
->next
= nodot
;
603 subfields
->opt
->name
= "skip";
604 subfields
->opt
->info
= NULL
;
606 else if ((size_t) rtx_next
[i
] == aindex
)
608 /* The 'next' field will be marked by the chain_next option. */
609 subfields
->opt
= xmalloc (sizeof (*subfields
->opt
));
610 subfields
->opt
->next
= nodot
;
611 subfields
->opt
->name
= "skip";
612 subfields
->opt
->info
= NULL
;
615 subfields
->opt
= nodot
;
618 flds
= xmalloc (sizeof (*flds
));
619 flds
->next
= old_flds
;
621 sname
= xasprintf ("rtx_def_%s", rtx_name
[i
]);
622 new_structure (sname
, 0, &lexer_line
, subfields
, NULL
);
623 flds
->type
= find_structure (sname
, 0);
624 flds
->line
.file
= __FILE__
;
625 flds
->line
.line
= __LINE__
;
626 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
627 flds
->opt
->next
= nodot
;
628 flds
->opt
->name
= "tag";
629 ftag
= xstrdup (rtx_name
[i
]);
630 for (nmindex
= 0; nmindex
< strlen (ftag
); nmindex
++)
631 ftag
[nmindex
] = TOUPPER (ftag
[nmindex
]);
632 flds
->opt
->info
= ftag
;
635 new_structure ("rtx_def_subunion", 1, &lexer_line
, flds
, nodot
);
636 return find_structure ("rtx_def_subunion", 1);
639 /* Handle `special("tree_exp")'. This is a special case for
640 field `operands' of struct tree_exp, which although it claims to contain
641 pointers to trees, actually sometimes contains pointers to RTL too.
642 Passed T, the old type of the field, and OPT its options. Returns
643 a new type for the field. */
646 adjust_field_tree_exp (t
, opt
)
648 options_p opt ATTRIBUTE_UNUSED
;
653 static const struct {
658 { "SAVE_EXPR", 2, 1 },
659 { "GOTO_SUBROUTINE_EXPR", 0, 2 },
660 { "RTL_EXPR", 0, 2 },
661 { "WITH_CLEANUP_EXPR", 2, 1 },
662 { "METHOD_CALL_EXPR", 3, 1 }
665 if (t
->kind
!= TYPE_ARRAY
)
667 error_at_line (&lexer_line
,
668 "special `tree_exp' must be applied to an array");
672 nodot
= xmalloc (sizeof (*nodot
));
677 flds
= xmalloc (sizeof (*flds
));
681 flds
->line
.file
= __FILE__
;
682 flds
->line
.line
= __LINE__
;
683 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
684 flds
->opt
->next
= nodot
;
685 flds
->opt
->name
= "length";
686 flds
->opt
->info
= "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
688 options_p oldopt
= flds
->opt
;
689 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
690 flds
->opt
->next
= oldopt
;
691 flds
->opt
->name
= "default";
692 flds
->opt
->info
= "";
695 for (i
= 0; i
< ARRAY_SIZE (data
); i
++)
697 pair_p old_flds
= flds
;
698 pair_p subfields
= NULL
;
703 r_index
< data
[i
].first_rtl
+ data
[i
].num_rtl
;
706 pair_p old_subf
= subfields
;
707 subfields
= xmalloc (sizeof (*subfields
));
708 subfields
->next
= old_subf
;
709 subfields
->name
= xasprintf ("[%d]", r_index
);
710 if (r_index
< data
[i
].first_rtl
)
711 subfields
->type
= t
->u
.a
.p
;
713 subfields
->type
= create_pointer (find_structure ("rtx_def", 0));
714 subfields
->line
.file
= __FILE__
;
715 subfields
->line
.line
= __LINE__
;
716 subfields
->opt
= nodot
;
719 flds
= xmalloc (sizeof (*flds
));
720 flds
->next
= old_flds
;
722 sname
= xasprintf ("tree_exp_%s", data
[i
].name
);
723 new_structure (sname
, 0, &lexer_line
, subfields
, NULL
);
724 flds
->type
= find_structure (sname
, 0);
725 flds
->line
.file
= __FILE__
;
726 flds
->line
.line
= __LINE__
;
727 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
728 flds
->opt
->next
= nodot
;
729 flds
->opt
->name
= "tag";
730 flds
->opt
->info
= data
[i
].name
;
733 new_structure ("tree_exp_subunion", 1, &lexer_line
, flds
, nodot
);
734 return find_structure ("tree_exp_subunion", 1);
737 /* Perform any special processing on a type T, about to become the type
738 of a field. Return the appropriate type for the field.
740 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
741 - Similarly for arrays of pointer-to-char;
742 - Converts structures for which a parameter is provided to
744 - Handles "special" options.
748 adjust_field_type (t
, opt
)
753 const int pointer_p
= t
->kind
== TYPE_POINTER
;
754 type_p params
[NUM_PARAM
];
758 for (i
= 0; i
< NUM_PARAM
; i
++)
761 for (; opt
; opt
= opt
->next
)
762 if (strcmp (opt
->name
, "length") == 0)
764 else if (strcmp (opt
->name
, "param_is") == 0
765 || (strncmp (opt
->name
, "param", 5) == 0
766 && ISDIGIT (opt
->name
[5])
767 && strcmp (opt
->name
+ 6, "_is") == 0))
769 int num
= ISDIGIT (opt
->name
[5]) ? opt
->name
[5] - '0' : 0;
771 if (! UNION_OR_STRUCT_P (t
)
772 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
774 error_at_line (&lexer_line
,
775 "option `%s' may only be applied to structures or structure pointers",
781 if (params
[num
] != NULL
)
782 error_at_line (&lexer_line
, "duplicate `%s' option", opt
->name
);
783 if (! ISDIGIT (opt
->name
[5]))
784 params
[num
] = create_pointer ((type_p
) opt
->info
);
786 params
[num
] = (type_p
) opt
->info
;
788 else if (strcmp (opt
->name
, "special") == 0)
790 const char *special_name
= (const char *)opt
->info
;
791 if (strcmp (special_name
, "tree_exp") == 0)
792 t
= adjust_field_tree_exp (t
, opt
);
793 else if (strcmp (special_name
, "rtx_def") == 0)
794 t
= adjust_field_rtx_def (t
, opt
);
796 error_at_line (&lexer_line
, "unknown special `%s'", special_name
);
805 realt
= find_param_structure (t
, params
);
806 t
= pointer_p
? create_pointer (realt
) : realt
;
811 && t
->u
.p
->kind
== TYPE_SCALAR
812 && (strcmp (t
->u
.p
->u
.sc
, "char") == 0
813 || strcmp (t
->u
.p
->u
.sc
, "unsigned char") == 0))
815 if (t
->kind
== TYPE_ARRAY
&& t
->u
.a
.p
->kind
== TYPE_POINTER
816 && t
->u
.a
.p
->u
.p
->kind
== TYPE_SCALAR
817 && (strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "char") == 0
818 || strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "unsigned char") == 0))
819 return create_array (&string_type
, t
->u
.a
.len
);
824 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
825 and information about the correspondance between token types and fields
826 in TYPEINFO. POS is used for error messages. */
829 note_yacc_type (o
, fields
, typeinfo
, pos
)
838 for (p
= typeinfo
; p
; p
= p
->next
)
845 if (p
->type
== (type_p
) 1)
850 for (pp
= typeinfo
; pp
; pp
= pp
->next
)
851 if (pp
->type
!= (type_p
) 1
852 && strcmp (pp
->opt
->info
, p
->opt
->info
) == 0)
861 for (m
= fields
; m
; m
= m
->next
)
862 if (strcmp (m
->name
, p
->name
) == 0)
866 error_at_line (&p
->line
,
867 "couldn't match fieldname `%s'", p
->name
);
878 || p
->type
== (type_p
) 1)
884 new_structure ("yy_union", 1, pos
, typeinfo
, o
);
885 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos
);
888 static void process_gc_options
PARAMS ((options_p
, enum gc_used_enum
,
889 int *, int *, int *));
890 static void set_gc_used_type
PARAMS ((type_p
, enum gc_used_enum
, type_p
*));
891 static void set_gc_used
PARAMS ((pair_p
));
893 /* Handle OPT for set_gc_used_type. */
896 process_gc_options (opt
, level
, maybe_undef
, pass_param
, length
)
898 enum gc_used_enum level
;
904 for (o
= opt
; o
; o
= o
->next
)
905 if (strcmp (o
->name
, "ptr_alias") == 0 && level
== GC_POINTED_TO
)
906 set_gc_used_type ((type_p
) o
->info
, GC_POINTED_TO
, NULL
);
907 else if (strcmp (o
->name
, "maybe_undef") == 0)
909 else if (strcmp (o
->name
, "use_params") == 0)
911 else if (strcmp (o
->name
, "length") == 0)
915 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
918 set_gc_used_type (t
, level
, param
)
920 enum gc_used_enum level
;
921 type_p param
[NUM_PARAM
];
923 if (t
->gc_used
>= level
)
936 process_gc_options (t
->u
.s
.opt
, level
, &dummy
, &dummy
, &dummy
);
938 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
943 process_gc_options (f
->opt
, level
, &maybe_undef
, &pass_param
,
946 if (length
&& f
->type
->kind
== TYPE_POINTER
)
947 set_gc_used_type (f
->type
->u
.p
, GC_USED
, NULL
);
948 else if (maybe_undef
&& f
->type
->kind
== TYPE_POINTER
)
949 set_gc_used_type (f
->type
->u
.p
, GC_MAYBE_POINTED_TO
, NULL
);
950 else if (pass_param
&& f
->type
->kind
== TYPE_POINTER
&& param
)
951 set_gc_used_type (find_param_structure (f
->type
->u
.p
, param
),
952 GC_POINTED_TO
, NULL
);
954 set_gc_used_type (f
->type
, GC_USED
, pass_param
? param
: NULL
);
960 set_gc_used_type (t
->u
.p
, GC_POINTED_TO
, NULL
);
964 set_gc_used_type (t
->u
.a
.p
, GC_USED
, param
);
967 case TYPE_LANG_STRUCT
:
968 for (t
= t
->u
.s
.lang_struct
; t
; t
= t
->next
)
969 set_gc_used_type (t
, level
, param
);
972 case TYPE_PARAM_STRUCT
:
975 for (i
= 0; i
< NUM_PARAM
; i
++)
976 if (t
->u
.param_struct
.param
[i
] != 0)
977 set_gc_used_type (t
->u
.param_struct
.param
[i
], GC_USED
, NULL
);
979 if (t
->u
.param_struct
.stru
->gc_used
== GC_POINTED_TO
)
980 level
= GC_POINTED_TO
;
983 t
->u
.param_struct
.stru
->gc_used
= GC_UNUSED
;
984 set_gc_used_type (t
->u
.param_struct
.stru
, level
,
985 t
->u
.param_struct
.param
);
993 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
996 set_gc_used (variables
)
1000 for (p
= variables
; p
; p
= p
->next
)
1001 set_gc_used_type (p
->type
, GC_USED
, NULL
);
1004 /* File mapping routines. For each input file, there is one output .c file
1005 (but some output files have many input files), and there is one .h file
1006 for the whole build. */
1008 /* The list of output files. */
1009 static outf_p output_files
;
1011 /* The output header file that is included into pretty much every
1015 /* Number of files specified in gtfiles. */
1016 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1018 /* Number of files in the language files array. */
1019 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1021 /* Length of srcdir name. */
1022 static int srcdir_len
= 0;
1024 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1025 outf_p base_files
[NUM_BASE_FILES
];
1027 static outf_p create_file
PARAMS ((const char *, const char *));
1028 static const char * get_file_basename
PARAMS ((const char *));
1030 /* Create and return an outf_p for a new file for NAME, to be called
1034 create_file (name
, oname
)
1038 static const char *const hdr
[] = {
1039 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
1041 "This file is part of GCC.\n",
1043 "GCC is free software; you can redistribute it and/or modify it under\n",
1044 "the terms of the GNU General Public License as published by the Free\n",
1045 "Software Foundation; either version 2, or (at your option) any later\n",
1048 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1049 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1050 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1051 "for more details.\n",
1053 "You should have received a copy of the GNU General Public License\n",
1054 "along with GCC; see the file COPYING. If not, write to the Free\n",
1055 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
1056 "02111-1307, USA. */\n",
1058 "/* This file is machine generated. Do not edit. */\n"
1063 f
= xcalloc (sizeof (*f
), 1);
1064 f
->next
= output_files
;
1068 oprintf (f
, "/* Type information for %s.\n", name
);
1069 for (i
= 0; i
< ARRAY_SIZE (hdr
); i
++)
1070 oprintf (f
, "%s", hdr
[i
]);
1074 /* Print, like fprintf, to O. */
1076 oprintf
VPARAMS ((outf_p o
, const char *format
, ...))
1081 VA_OPEN (ap
, format
);
1082 VA_FIXEDARG (ap
, outf_p
, o
);
1083 VA_FIXEDARG (ap
, const char *, format
);
1084 slength
= xvasprintf (&s
, format
, ap
);
1086 if (o
->bufused
+ slength
> o
->buflength
)
1088 size_t new_len
= o
->buflength
;
1093 } while (o
->bufused
+ slength
>= new_len
);
1094 o
->buf
= xrealloc (o
->buf
, new_len
);
1095 o
->buflength
= new_len
;
1097 memcpy (o
->buf
+ o
->bufused
, s
, slength
);
1098 o
->bufused
+= slength
;
1103 /* Open the global header file and the language-specific header files. */
1110 header_file
= create_file ("GCC", "gtype-desc.h");
1112 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1113 base_files
[i
] = create_file (lang_dir_names
[i
],
1114 xasprintf ("gtype-%s.h", lang_dir_names
[i
]));
1116 /* gtype-desc.c is a little special, so we create it here. */
1118 /* The order of files here matters very much. */
1119 static const char *const ifiles
[] = {
1120 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1121 "hashtab.h", "splay-tree.h", "bitmap.h", "tree.h", "rtl.h",
1122 "function.h", "insn-config.h", "expr.h", "hard-reg-set.h",
1123 "basic-block.h", "cselib.h", "insn-addr.h", "ssa.h", "optabs.h",
1124 "libfuncs.h", "debug.h", "ggc.h",
1127 const char *const *ifp
;
1128 outf_p gtype_desc_c
;
1130 gtype_desc_c
= create_file ("GCC", "gtype-desc.c");
1131 for (ifp
= ifiles
; *ifp
; ifp
++)
1132 oprintf (gtype_desc_c
, "#include \"%s\"\n", *ifp
);
1136 /* Determine the pathname to F relative to $(srcdir). */
1139 get_file_basename (f
)
1142 const char *basename
;
1145 basename
= strrchr (f
, '/');
1152 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1158 s1
= basename
- strlen (lang_dir_names
[i
]) - 1;
1159 s2
= lang_dir_names
[i
];
1162 if (l1
>= l2
&& !memcmp (s1
, s2
, l2
))
1165 if ((basename
- f
- 1) != srcdir_len
)
1166 abort (); /* Match is wrong - should be preceded by $srcdir. */
1174 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1175 INPUT_FILE is used by <lang>.
1177 This function should be written to assume that a file _is_ used
1178 if the situation is unclear. If it wrongly assumes a file _is_ used,
1179 a linker error will result. If it wrongly assumes a file _is not_ used,
1180 some GC roots may be missed, which is a much harder-to-debug problem. */
1183 get_base_file_bitmap (input_file
)
1184 const char *input_file
;
1186 const char *basename
= get_file_basename (input_file
);
1187 const char *slashpos
= strchr (basename
, '/');
1195 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1196 if ((size_t)(slashpos
- basename
) == strlen (lang_dir_names
[i
])
1197 && memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0)
1199 /* It's in a language directory, set that language. */
1204 abort (); /* Should have found the language. */
1207 /* If it's in any config-lang.in, then set for the languages
1212 for (j
= 0; j
< NUM_LANG_FILES
; j
++)
1214 if (!strcmp(input_file
, lang_files
[j
]))
1216 for (k
= 0; k
< NUM_BASE_FILES
; k
++)
1218 if (!strcmp(lang_dir_names
[k
], langs_for_lang_files
[j
]))
1224 /* Otherwise, set all languages. */
1226 bitmap
= (1 << NUM_BASE_FILES
) - 1;
1231 /* An output file, suitable for definitions, that can see declarations
1232 made in INPUT_FILE and is linked into every language that uses
1236 get_output_file_with_visibility (input_file
)
1237 const char *input_file
;
1241 const char *basename
;
1242 const char *for_name
;
1243 const char *output_name
;
1245 /* This can happen when we need a file with visibility on a
1246 structure that we've never seen. We have to just hope that it's
1247 globally visible. */
1248 if (input_file
== NULL
)
1249 input_file
= "system.h";
1251 /* Determine the output file name. */
1252 basename
= get_file_basename (input_file
);
1254 len
= strlen (basename
);
1255 if ((len
> 2 && memcmp (basename
+len
-2, ".c", 2) == 0)
1256 || (len
> 2 && memcmp (basename
+len
-2, ".y", 2) == 0)
1257 || (len
> 3 && memcmp (basename
+len
-3, ".in", 3) == 0))
1261 output_name
= s
= xasprintf ("gt-%s", basename
);
1262 for (; *s
!= '.'; s
++)
1263 if (! ISALNUM (*s
) && *s
!= '-')
1265 memcpy (s
, ".h", sizeof (".h"));
1266 for_name
= basename
;
1268 else if (strcmp (basename
, "c-common.h") == 0)
1269 output_name
= "gt-c-common.h", for_name
= "c-common.c";
1270 else if (strcmp (basename
, "c-tree.h") == 0)
1271 output_name
= "gt-c-decl.h", for_name
= "c-decl.c";
1276 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1277 if (memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0
1278 && basename
[strlen(lang_dir_names
[i
])] == '/')
1279 return base_files
[i
];
1281 output_name
= "gtype-desc.c";
1285 /* Look through to see if we've ever seen this output filename before. */
1286 for (r
= output_files
; r
; r
= r
->next
)
1287 if (strcmp (r
->name
, output_name
) == 0)
1290 /* If not, create it. */
1291 r
= create_file (for_name
, output_name
);
1296 /* The name of an output file, suitable for definitions, that can see
1297 declarations made in INPUT_FILE and is linked into every language
1298 that uses INPUT_FILE. */
1301 get_output_file_name (input_file
)
1302 const char *input_file
;
1304 return get_output_file_with_visibility (input_file
)->name
;
1307 /* Copy the output to its final destination,
1308 but don't unnecessarily change modification times. */
1310 static void close_output_files
PARAMS ((void));
1313 close_output_files ()
1317 for (of
= output_files
; of
; of
= of
->next
)
1321 newfile
= fopen (of
->name
, "r");
1322 if (newfile
!= NULL
)
1327 for (i
= 0; i
< of
->bufused
; i
++)
1330 ch
= fgetc (newfile
);
1331 if (ch
== EOF
|| ch
!= (unsigned char) of
->buf
[i
])
1334 no_write_p
= i
== of
->bufused
&& fgetc (newfile
) == EOF
;
1341 newfile
= fopen (of
->name
, "w");
1342 if (newfile
== NULL
)
1344 perror ("opening output file");
1347 if (fwrite (of
->buf
, 1, of
->bufused
, newfile
) != of
->bufused
)
1349 perror ("writing output file");
1352 if (fclose (newfile
) != 0)
1354 perror ("closing output file");
1367 static void output_escaped_param
PARAMS ((outf_p
, const char *, const char *,
1368 const char *, const char *,
1370 static void output_mangled_typename
PARAMS ((outf_p
, type_p
));
1371 static void write_gc_structure_fields
1372 PARAMS ((outf_p
, type_p
, const char *, const char *, options_p
,
1373 int, struct fileloc
*, lang_bitmap
, type_p
*));
1374 static void write_gc_marker_routine_for_structure
PARAMS ((type_p
, type_p
,
1376 static void write_gc_types
PARAMS ((type_p structures
, type_p param_structs
));
1377 static void write_enum_defn
PARAMS ((type_p structures
, type_p param_structs
));
1378 static void put_mangled_filename
PARAMS ((outf_p
, const char *));
1379 static void finish_root_table
PARAMS ((struct flist
*flp
, const char *pfx
,
1380 const char *tname
, const char *lastname
,
1382 static void write_gc_root
PARAMS ((outf_p
, pair_p
, type_p
, const char *, int,
1383 struct fileloc
*, const char *));
1384 static void write_gc_roots
PARAMS ((pair_p
));
1386 static int gc_counter
;
1388 /* Print PARAM to OF processing escapes. VAL references the current object,
1389 PREV_VAL the object containing the current object, ONAME is the name
1390 of the option and LINE is used to print error messages. */
1393 output_escaped_param (of
, param
, val
, prev_val
, oname
, line
)
1397 const char *prev_val
;
1399 struct fileloc
*line
;
1403 for (p
= param
; *p
; p
++)
1405 oprintf (of
, "%c", *p
);
1409 oprintf (of
, "(%s)", val
);
1412 oprintf (of
, "(*x)");
1415 oprintf (of
, "(%s)", prev_val
);
1419 const char *pp
= val
+ strlen (val
);
1420 while (pp
[-1] == ']')
1423 oprintf (of
, "%s", pp
);
1427 error_at_line (line
, "`%s' option contains bad escape %c%c",
1432 /* Print a mangled name representing T to OF. */
1435 output_mangled_typename (of
, t
)
1441 else switch (t
->kind
)
1445 output_mangled_typename (of
, t
->u
.p
);
1455 case TYPE_LANG_STRUCT
:
1456 oprintf (of
, "%lu%s", (unsigned long) strlen (t
->u
.s
.tag
), t
->u
.s
.tag
);
1458 case TYPE_PARAM_STRUCT
:
1461 for (i
= 0; i
< NUM_PARAM
; i
++)
1462 if (t
->u
.param_struct
.param
[i
] != NULL
)
1463 output_mangled_typename (of
, t
->u
.param_struct
.param
[i
]);
1464 output_mangled_typename (of
, t
->u
.param_struct
.stru
);
1472 /* Write out code to OF which marks the fields of S. VAL references
1473 the current object, PREV_VAL the object containing the current
1474 object, OPTS is a list of options to apply, INDENT is the current
1475 indentation level, LINE is used to print error messages, BITMAP
1476 indicates which languages to print the structure for, and PARAM is
1477 the current parameter (from an enclosing param_is option). */
1480 write_gc_structure_fields (of
, s
, val
, prev_val
, opts
, indent
, line
, bitmap
,
1485 const char *prev_val
;
1488 struct fileloc
*line
;
1493 int seen_default
= 0;
1495 if (! s
->u
.s
.line
.file
)
1496 error_at_line (line
, "incomplete structure `%s'", s
->u
.s
.tag
);
1497 else if ((s
->u
.s
.bitmap
& bitmap
) != bitmap
)
1499 error_at_line (line
, "structure defined for mismatching languages");
1500 error_at_line (&s
->u
.s
.line
, "one structure defined here");
1503 if (s
->kind
== TYPE_UNION
)
1505 const char *tagexpr
= NULL
;
1508 for (oo
= opts
; oo
; oo
= oo
->next
)
1509 if (strcmp (oo
->name
, "desc") == 0)
1510 tagexpr
= (const char *)oo
->info
;
1511 if (tagexpr
== NULL
)
1514 error_at_line (line
, "missing `desc' option");
1517 oprintf (of
, "%*sswitch (", indent
, "");
1518 output_escaped_param (of
, tagexpr
, val
, prev_val
, "desc", line
);
1519 oprintf (of
, ")\n");
1521 oprintf (of
, "%*s{\n", indent
, "");
1524 for (f
= s
->u
.s
.fields
; f
; f
= f
->next
)
1526 const char *tagid
= NULL
;
1527 const char *length
= NULL
;
1530 int maybe_undef_p
= 0;
1531 int use_param_num
= -1;
1532 int use_params_p
= 0;
1533 int needs_cast_p
= 0;
1536 const char *dot
= ".";
1538 for (oo
= f
->opt
; oo
; oo
= oo
->next
)
1539 if (strcmp (oo
->name
, "length") == 0)
1540 length
= (const char *)oo
->info
;
1541 else if (strcmp (oo
->name
, "maybe_undef") == 0)
1543 else if (strcmp (oo
->name
, "tag") == 0)
1544 tagid
= (const char *)oo
->info
;
1545 else if (strcmp (oo
->name
, "special") == 0)
1547 else if (strcmp (oo
->name
, "skip") == 0)
1549 else if (strcmp (oo
->name
, "default") == 0)
1551 else if (strcmp (oo
->name
, "desc") == 0)
1553 else if (strcmp (oo
->name
, "descbits") == 0)
1555 else if (strcmp (oo
->name
, "param_is") == 0)
1557 else if (strncmp (oo
->name
, "use_param", 9) == 0
1558 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1559 use_param_num
= oo
->name
[9] == '\0' ? 0 : oo
->name
[9] - '0';
1560 else if (strcmp (oo
->name
, "use_params") == 0)
1562 else if (strcmp (oo
->name
, "dot") == 0)
1563 dot
= (const char *)oo
->info
;
1565 error_at_line (&f
->line
, "unknown field option `%s'\n", oo
->name
);
1572 int pointer_p
= t
->kind
== TYPE_POINTER
;
1576 t
= find_param_structure (t
, param
);
1578 t
= create_pointer (t
);
1581 if (use_param_num
!= -1)
1583 if (param
!= NULL
&& param
[use_param_num
] != NULL
)
1585 type_p nt
= param
[use_param_num
];
1587 if (t
->kind
== TYPE_ARRAY
)
1588 nt
= create_array (nt
, t
->u
.a
.len
);
1589 else if (length
!= NULL
&& t
->kind
== TYPE_POINTER
)
1590 nt
= create_pointer (nt
);
1591 needs_cast_p
= (t
->kind
!= TYPE_POINTER
1592 && nt
->kind
== TYPE_POINTER
);
1595 else if (s
->kind
!= TYPE_UNION
)
1596 error_at_line (&f
->line
, "no parameter defined");
1599 if (t
->kind
== TYPE_SCALAR
1600 || (t
->kind
== TYPE_ARRAY
1601 && t
->u
.a
.p
->kind
== TYPE_SCALAR
))
1604 seen_default
|= default_p
;
1607 && (t
->kind
!= TYPE_POINTER
1608 || t
->u
.p
->kind
!= TYPE_STRUCT
))
1609 error_at_line (&f
->line
,
1610 "field `%s' has invalid option `maybe_undef_p'\n",
1612 if (s
->kind
== TYPE_UNION
)
1616 oprintf (of
, "%*scase %s:\n", indent
, "", tagid
);
1621 oprintf (of
, "%*sdefault:\n", indent
, "");
1625 error_at_line (&f
->line
, "field `%s' has no tag", f
->name
);
1634 /* Do nothing; strings go in the string pool. */
1637 case TYPE_LANG_STRUCT
:
1640 for (ti
= t
->u
.s
.lang_struct
; ti
; ti
= ti
->next
)
1641 if (ti
->u
.s
.bitmap
& bitmap
)
1648 error_at_line (&f
->line
,
1649 "structure not defined for this language");
1653 /* Fall through... */
1659 newval
= xasprintf ("%s%s%s", val
, dot
, f
->name
);
1660 write_gc_structure_fields (of
, t
, newval
, val
, f
->opt
, indent
,
1661 &f
->line
, bitmap
, param
);
1670 && t
->u
.p
->u
.s
.line
.file
== NULL
)
1671 oprintf (of
, "%*sif (%s%s%s) abort();\n", indent
, "",
1673 else if (UNION_OR_STRUCT_P (t
->u
.p
)
1674 || t
->u
.p
->kind
== TYPE_PARAM_STRUCT
)
1676 oprintf (of
, "%*sgt_ggc_m_", indent
, "");
1677 output_mangled_typename (of
, t
->u
.p
);
1680 oprintf (of
, "(%s %s *)",
1681 UNION_P (t
->u
.p
) ? "union" : "struct",
1683 oprintf (of
, "%s%s%s);\n", val
, dot
, f
->name
);
1686 error_at_line (&f
->line
, "field `%s' is pointer to scalar",
1690 else if (t
->u
.p
->kind
== TYPE_SCALAR
1691 || t
->u
.p
->kind
== TYPE_STRING
)
1692 oprintf (of
, "%*sggc_mark (%s%s%s);\n", indent
, "",
1696 int loopcounter
= ++gc_counter
;
1698 oprintf (of
, "%*sif (%s%s%s != NULL) {\n", indent
, "",
1701 oprintf (of
, "%*ssize_t i%d;\n", indent
, "", loopcounter
);
1702 oprintf (of
, "%*sggc_set_mark (%s%s%s);\n", indent
, "",
1704 oprintf (of
, "%*sfor (i%d = 0; i%d < (size_t)(", indent
, "",
1705 loopcounter
, loopcounter
);
1706 output_escaped_param (of
, length
, val
, prev_val
, "length", line
);
1707 oprintf (of
, "); i%d++) {\n", loopcounter
);
1709 switch (t
->u
.p
->kind
)
1716 newval
= xasprintf ("%s%s%s[i%d]", val
, dot
, f
->name
,
1718 write_gc_structure_fields (of
, t
->u
.p
, newval
, val
,
1719 f
->opt
, indent
, &f
->line
,
1725 if (UNION_OR_STRUCT_P (t
->u
.p
->u
.p
)
1726 || t
->u
.p
->u
.p
->kind
== TYPE_PARAM_STRUCT
)
1728 oprintf (of
, "%*sgt_ggc_m_", indent
, "");
1729 output_mangled_typename (of
, t
->u
.p
->u
.p
);
1730 oprintf (of
, " (%s%s%s[i%d]);\n", val
, dot
, f
->name
,
1734 error_at_line (&f
->line
,
1735 "field `%s' is array of pointer to scalar",
1739 error_at_line (&f
->line
,
1740 "field `%s' is array of unimplemented type",
1745 oprintf (of
, "%*s}\n", indent
, "");
1747 oprintf (of
, "%*s}\n", indent
, "");
1753 int loopcounter
= ++gc_counter
;
1758 (strcmp (t
->u
.a
.len
, "0") == 0
1759 || strcmp (t
->u
.a
.len
, "1") == 0))
1760 error_at_line (&f
->line
,
1761 "field `%s' is array of size %s",
1762 f
->name
, t
->u
.a
.len
);
1764 /* Arrays of scalars can be ignored. */
1765 for (ta
= t
; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
)
1767 if (ta
->kind
== TYPE_SCALAR
1768 || ta
->kind
== TYPE_STRING
)
1771 oprintf (of
, "%*s{\n", indent
, "");
1774 for (ta
= t
, i
= 0; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
, i
++)
1776 oprintf (of
, "%*ssize_t i%d_%d;\n",
1777 indent
, "", loopcounter
, i
);
1778 oprintf (of
, "%*sconst size_t ilimit%d_%d = (",
1779 indent
, "", loopcounter
, i
);
1780 if (i
== 0 && length
!= NULL
)
1781 output_escaped_param (of
, length
, val
, prev_val
,
1784 oprintf (of
, "%s", ta
->u
.a
.len
);
1785 oprintf (of
, ");\n");
1788 for (ta
= t
, i
= 0; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
, i
++)
1791 "%*sfor (i%d_%d = 0; i%d_%d < ilimit%d_%d; i%d_%d++) {\n",
1792 indent
, "", loopcounter
, i
, loopcounter
, i
,
1793 loopcounter
, i
, loopcounter
, i
);
1797 if (ta
->kind
== TYPE_POINTER
1798 && (UNION_OR_STRUCT_P (ta
->u
.p
)
1799 || ta
->u
.p
->kind
== TYPE_PARAM_STRUCT
))
1801 oprintf (of
, "%*sgt_ggc_m_", indent
, "");
1802 output_mangled_typename (of
, ta
->u
.p
);
1803 oprintf (of
, " (%s%s%s", val
, dot
, f
->name
);
1805 ta
->kind
== TYPE_ARRAY
;
1806 ta
= ta
->u
.a
.p
, i
++)
1807 oprintf (of
, "[i%d_%d]", loopcounter
, i
);
1808 oprintf (of
, ");\n");
1810 else if (ta
->kind
== TYPE_STRUCT
|| ta
->kind
== TYPE_UNION
)
1815 len
= strlen (val
) + strlen (f
->name
) + 2;
1816 for (ta
= t
; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
)
1817 len
+= sizeof ("[i_]") + 2*6;
1819 newval
= xmalloc (len
);
1820 sprintf (newval
, "%s%s%s", val
, dot
, f
->name
);
1822 ta
->kind
== TYPE_ARRAY
;
1823 ta
= ta
->u
.a
.p
, i
++)
1824 sprintf (newval
+ strlen (newval
), "[i%d_%d]",
1826 write_gc_structure_fields (of
, t
->u
.p
, newval
, val
,
1827 f
->opt
, indent
, &f
->line
, bitmap
,
1831 else if (ta
->kind
== TYPE_POINTER
&& ta
->u
.p
->kind
== TYPE_SCALAR
1832 && use_param_num
!= -1 && param
== NULL
)
1833 oprintf (of
, "%*sabort();\n", indent
, "");
1835 error_at_line (&f
->line
,
1836 "field `%s' is array of unimplemented type",
1838 for (ta
= t
, i
= 0; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
, i
++)
1841 oprintf (of
, "%*s}\n", indent
, "");
1845 oprintf (of
, "%*s}\n", indent
, "");
1850 error_at_line (&f
->line
,
1851 "field `%s' is unimplemented type",
1856 if (s
->kind
== TYPE_UNION
)
1858 oprintf (of
, "%*sbreak;\n", indent
, "");
1862 if (s
->kind
== TYPE_UNION
)
1866 oprintf (of
, "%*sdefault:\n", indent
, "");
1867 oprintf (of
, "%*s break;\n", indent
, "");
1869 oprintf (of
, "%*s}\n", indent
, "");
1874 /* Write out a marker routine for S. PARAM is the parameter from an
1875 enclosing PARAM_IS option. */
1878 write_gc_marker_routine_for_structure (orig_s
, s
, param
)
1884 const char *fn
= s
->u
.s
.line
.file
;
1886 const char *chain_next
= NULL
;
1887 const char *chain_prev
= NULL
;
1890 /* This is a hack, and not the good kind either. */
1891 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
1892 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
1893 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
1894 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
1896 f
= get_output_file_with_visibility (fn
);
1898 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
1899 if (strcmp (opt
->name
, "chain_next") == 0)
1900 chain_next
= (const char *) opt
->info
;
1901 else if (strcmp (opt
->name
, "chain_prev") == 0)
1902 chain_prev
= (const char *) opt
->info
;
1904 if (chain_prev
!= NULL
&& chain_next
== NULL
)
1905 error_at_line (&s
->u
.s
.line
, "chain_prev without chain_next");
1908 oprintf (f
, "void\n");
1910 oprintf (f
, "gt_ggc_mx_%s", s
->u
.s
.tag
);
1913 oprintf (f
, "gt_ggc_m_");
1914 output_mangled_typename (f
, orig_s
);
1916 oprintf (f
, " (x_p)\n");
1917 oprintf (f
, " void *x_p;\n");
1919 oprintf (f
, " %s %s * %sx = (%s %s *)x_p;\n",
1920 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
1921 chain_next
== NULL
? "const " : "",
1922 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
1923 if (chain_next
!= NULL
)
1924 oprintf (f
, " %s %s * xlimit = x;\n",
1925 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
1926 if (chain_next
== NULL
)
1927 oprintf (f
, " if (ggc_test_and_set_mark (x))\n");
1930 oprintf (f
, " while (ggc_test_and_set_mark (xlimit))\n");
1931 oprintf (f
, " xlimit = (");
1932 output_escaped_param (f
, chain_next
, "*xlimit", "*xlimit",
1933 "chain_next", &s
->u
.s
.line
);
1934 oprintf (f
, ");\n");
1935 if (chain_prev
!= NULL
)
1937 oprintf (f
, " if (x != xlimit)\n");
1938 oprintf (f
, " for (;;)\n");
1939 oprintf (f
, " {\n");
1940 oprintf (f
, " %s %s * const xprev = (",
1941 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
1942 output_escaped_param (f
, chain_prev
, "*x", "*x",
1943 "chain_prev", &s
->u
.s
.line
);
1944 oprintf (f
, ");\n");
1945 oprintf (f
, " if (xprev == NULL) break;\n");
1946 oprintf (f
, " x = xprev;\n");
1947 oprintf (f
, " ggc_set_mark (xprev);\n");
1948 oprintf (f
, " }\n");
1950 oprintf (f
, " while (x != xlimit)\n");
1952 oprintf (f
, " {\n");
1955 write_gc_structure_fields (f
, s
, "(*x)", "not valid postage",
1956 s
->u
.s
.opt
, 6, &s
->u
.s
.line
, s
->u
.s
.bitmap
,
1959 if (chain_next
!= NULL
)
1961 oprintf (f
, " x = (");
1962 output_escaped_param (f
, chain_next
, "*x", "*x",
1963 "chain_next", &s
->u
.s
.line
);
1964 oprintf (f
, ");\n");
1967 oprintf (f
, " }\n");
1971 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
1974 write_gc_types (structures
, param_structs
)
1976 type_p param_structs
;
1980 oprintf (header_file
, "\n/* GC marker procedures. */\n");
1981 for (s
= structures
; s
; s
= s
->next
)
1982 if (s
->gc_used
== GC_POINTED_TO
1983 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
1987 if (s
->gc_used
== GC_MAYBE_POINTED_TO
1988 && s
->u
.s
.line
.file
== NULL
)
1991 oprintf (header_file
, "#define gt_ggc_m_");
1992 output_mangled_typename (header_file
, s
);
1993 oprintf (header_file
, "(X) do { \\\n");
1994 oprintf (header_file
,
1995 " if (X != NULL) gt_ggc_mx_%s (X);\\\n", s
->u
.s
.tag
);
1996 oprintf (header_file
,
1999 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2000 if (strcmp (opt
->name
, "ptr_alias") == 0)
2002 type_p t
= (type_p
) opt
->info
;
2003 if (t
->kind
== TYPE_STRUCT
2004 || t
->kind
== TYPE_UNION
2005 || t
->kind
== TYPE_LANG_STRUCT
)
2006 oprintf (header_file
,
2007 "#define gt_ggc_mx_%s gt_ggc_mx_%s\n",
2008 s
->u
.s
.tag
, t
->u
.s
.tag
);
2010 error_at_line (&s
->u
.s
.line
,
2011 "structure alias is not a structure");
2017 /* Declare the marker procedure only once. */
2018 oprintf (header_file
,
2019 "extern void gt_ggc_mx_%s PARAMS ((void *));\n",
2022 if (s
->u
.s
.line
.file
== NULL
)
2024 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2029 if (s
->kind
== TYPE_LANG_STRUCT
)
2032 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2033 write_gc_marker_routine_for_structure (s
, ss
, NULL
);
2036 write_gc_marker_routine_for_structure (s
, s
, NULL
);
2039 for (s
= param_structs
; s
; s
= s
->next
)
2040 if (s
->gc_used
== GC_POINTED_TO
)
2042 type_p
* param
= s
->u
.param_struct
.param
;
2043 type_p stru
= s
->u
.param_struct
.stru
;
2045 /* Declare the marker procedure. */
2046 oprintf (header_file
, "extern void gt_ggc_m_");
2047 output_mangled_typename (header_file
, s
);
2048 oprintf (header_file
, " PARAMS ((void *));\n");
2050 if (stru
->u
.s
.line
.file
== NULL
)
2052 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2057 if (stru
->kind
== TYPE_LANG_STRUCT
)
2060 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2061 write_gc_marker_routine_for_structure (s
, ss
, param
);
2064 write_gc_marker_routine_for_structure (s
, stru
, param
);
2068 /* Write out the 'enum' definition for gt_types_enum. */
2071 write_enum_defn (structures
, param_structs
)
2073 type_p param_structs
;
2077 oprintf (header_file
, "\n/* Enumeration of types known. */\n");
2078 oprintf (header_file
, "enum gt_types_enum {\n");
2079 for (s
= structures
; s
; s
= s
->next
)
2080 if (s
->gc_used
== GC_POINTED_TO
2081 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2083 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2084 && s
->u
.s
.line
.file
== NULL
)
2087 oprintf (header_file
, " gt_ggc_e_");
2088 output_mangled_typename (header_file
, s
);
2089 oprintf (header_file
, ", \n");
2091 for (s
= param_structs
; s
; s
= s
->next
)
2092 if (s
->gc_used
== GC_POINTED_TO
)
2094 oprintf (header_file
, " gt_e_");
2095 output_mangled_typename (header_file
, s
);
2096 oprintf (header_file
, ", \n");
2098 oprintf (header_file
, " gt_types_enum_last\n");
2099 oprintf (header_file
, "};\n");
2103 /* Mangle FN and print it to F. */
2106 put_mangled_filename (f
, fn
)
2110 const char *name
= get_output_file_name (fn
);
2111 for (; *name
!= 0; name
++)
2112 if (ISALNUM (*name
))
2113 oprintf (f
, "%c", *name
);
2115 oprintf (f
, "%c", '_');
2118 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2119 LASTNAME, and NAME are all strings to insert in various places in
2120 the resulting code. */
2123 finish_root_table (flp
, pfx
, lastname
, tname
, name
)
2127 const char *lastname
;
2131 unsigned started_bitmap
= 0;
2133 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2134 if (fli2
->started_p
)
2136 oprintf (fli2
->f
, " %s\n", lastname
);
2137 oprintf (fli2
->f
, "};\n\n");
2140 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2141 if (fli2
->started_p
)
2143 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2146 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2149 oprintf (base_files
[fnum
],
2150 "extern const struct %s gt_ggc_%s_",
2152 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2153 oprintf (base_files
[fnum
], "[];\n");
2157 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2158 if (fli2
->started_p
)
2160 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2163 fli2
->started_p
= 0;
2165 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2168 if (! (started_bitmap
& (1 << fnum
)))
2170 oprintf (base_files
[fnum
],
2171 "const struct %s * const %s[] = {\n",
2173 started_bitmap
|= 1 << fnum
;
2175 oprintf (base_files
[fnum
], " gt_ggc_%s_", pfx
);
2176 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2177 oprintf (base_files
[fnum
], ",\n");
2185 for (bitmap
= started_bitmap
, fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2188 oprintf (base_files
[fnum
], " NULL\n");
2189 oprintf (base_files
[fnum
], "};\n");
2194 /* Write out to F the table entry and any marker routines needed to
2195 mark NAME as TYPE. The original variable is V, at LINE.
2196 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2197 is nonzero iff we are building the root table for hash table caches. */
2200 write_gc_root (f
, v
, type
, name
, has_length
, line
, if_marked
)
2206 struct fileloc
*line
;
2207 const char *if_marked
;
2214 for (fld
= type
->u
.s
.fields
; fld
; fld
= fld
->next
)
2217 const char *desc
= NULL
;
2220 for (o
= fld
->opt
; o
; o
= o
->next
)
2221 if (strcmp (o
->name
, "skip") == 0)
2223 else if (strcmp (o
->name
, "desc") == 0)
2224 desc
= (const char *)o
->info
;
2226 error_at_line (line
,
2227 "field `%s' of global `%s' has unknown option `%s'",
2228 fld
->name
, name
, o
->name
);
2232 else if (desc
&& fld
->type
->kind
== TYPE_UNION
)
2234 pair_p validf
= NULL
;
2237 for (ufld
= fld
->type
->u
.s
.fields
; ufld
; ufld
= ufld
->next
)
2239 const char *tag
= NULL
;
2242 for (oo
= ufld
->opt
; oo
; oo
= oo
->next
)
2243 if (strcmp (oo
->name
, "tag") == 0)
2244 tag
= (const char *)oo
->info
;
2245 if (tag
== NULL
|| strcmp (tag
, desc
) != 0)
2248 error_at_line (line
,
2249 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2250 name
, fld
->name
, validf
->name
,
2251 name
, fld
->name
, ufld
->name
,
2258 newname
= xasprintf ("%s.%s.%s",
2259 name
, fld
->name
, validf
->name
);
2260 write_gc_root (f
, v
, validf
->type
, newname
, 0, line
,
2266 error_at_line (line
,
2267 "global `%s.%s' has `desc' option but is not union",
2272 newname
= xasprintf ("%s.%s", name
, fld
->name
);
2273 write_gc_root (f
, v
, fld
->type
, newname
, 0, line
, if_marked
);
2283 newname
= xasprintf ("%s[0]", name
);
2284 write_gc_root (f
, v
, type
->u
.a
.p
, newname
, has_length
, line
, if_marked
);
2293 oprintf (f
, " {\n");
2294 oprintf (f
, " &%s,\n", name
);
2297 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2299 oprintf (f
, " * (%s)", ap
->u
.a
.len
);
2300 else if (ap
== v
->type
)
2301 oprintf (f
, " * ARRAY_SIZE (%s)", v
->name
);
2303 oprintf (f
, " sizeof (%s", v
->name
);
2304 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2306 oprintf (f
, "),\n");
2310 if (! has_length
&& UNION_OR_STRUCT_P (tp
))
2312 oprintf (f
, " >_ggc_mx_%s\n", tp
->u
.s
.tag
);
2314 else if (! has_length
&& tp
->kind
== TYPE_PARAM_STRUCT
)
2316 oprintf (f
, " >_ggc_m_");
2317 output_mangled_typename (f
, tp
);
2320 && (tp
->kind
== TYPE_POINTER
|| UNION_OR_STRUCT_P (tp
)))
2322 oprintf (f
, " >_ggc_ma_%s", name
);
2326 error_at_line (line
,
2327 "global `%s' is pointer to unimplemented type",
2331 oprintf (f
, ",\n &%s", if_marked
);
2332 oprintf (f
, "\n },\n");
2341 error_at_line (line
,
2342 "global `%s' is unimplemented type",
2347 /* Output a table describing the locations and types of VARIABLES. */
2350 write_gc_roots (variables
)
2354 struct flist
*flp
= NULL
;
2356 for (v
= variables
; v
; v
= v
->next
)
2358 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2360 const char *length
= NULL
;
2361 int deletable_p
= 0;
2364 for (o
= v
->opt
; o
; o
= o
->next
)
2365 if (strcmp (o
->name
, "length") == 0)
2366 length
= (const char *)o
->info
;
2367 else if (strcmp (o
->name
, "deletable") == 0)
2369 else if (strcmp (o
->name
, "param_is") == 0)
2371 else if (strncmp (o
->name
, "param", 5) == 0
2372 && ISDIGIT (o
->name
[5])
2373 && strcmp (o
->name
+ 6, "_is") == 0)
2375 else if (strcmp (o
->name
, "if_marked") == 0)
2378 error_at_line (&v
->line
,
2379 "global `%s' has unknown option `%s'",
2382 for (fli
= flp
; fli
; fli
= fli
->next
)
2387 fli
= xmalloc (sizeof (*fli
));
2391 fli
->name
= v
->line
.file
;
2394 oprintf (f
, "\n/* GC roots. */\n\n");
2399 && v
->type
->kind
== TYPE_POINTER
2400 && (v
->type
->u
.p
->kind
== TYPE_POINTER
2401 || v
->type
->u
.p
->kind
== TYPE_STRUCT
))
2403 oprintf (f
, "static void gt_ggc_ma_%s PARAMS ((void *));\n",
2405 oprintf (f
, "static void\ngt_ggc_ma_%s (x_p)\n void *x_p;\n",
2408 oprintf (f
, " size_t i;\n");
2410 if (v
->type
->u
.p
->kind
== TYPE_POINTER
)
2412 type_p s
= v
->type
->u
.p
->u
.p
;
2414 oprintf (f
, " %s %s ** const x = (%s %s **)x_p;\n",
2415 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2416 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2417 oprintf (f
, " if (ggc_test_and_set_mark (x))\n");
2418 oprintf (f
, " for (i = 0; i < (%s); i++)\n", length
);
2419 if (! UNION_OR_STRUCT_P (s
)
2420 && ! s
->kind
== TYPE_PARAM_STRUCT
)
2422 error_at_line (&v
->line
,
2423 "global `%s' has unsupported ** type",
2428 oprintf (f
, " gt_ggc_m_");
2429 output_mangled_typename (f
, s
);
2430 oprintf (f
, " (x[i]);\n");
2434 type_p s
= v
->type
->u
.p
;
2436 oprintf (f
, " %s %s * const x = (%s %s *)x_p;\n",
2437 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2438 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2439 oprintf (f
, " if (ggc_test_and_set_mark (x))\n");
2440 oprintf (f
, " for (i = 0; i < (%s); i++)\n", length
);
2441 oprintf (f
, " {\n");
2442 write_gc_structure_fields (f
, s
, "x[i]", "x[i]",
2443 v
->opt
, 8, &v
->line
, s
->u
.s
.bitmap
,
2445 oprintf (f
, " }\n");
2448 oprintf (f
, "}\n\n");
2452 for (v
= variables
; v
; v
= v
->next
)
2454 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2460 for (o
= v
->opt
; o
; o
= o
->next
)
2461 if (strcmp (o
->name
, "length") == 0)
2463 else if (strcmp (o
->name
, "deletable") == 0
2464 || strcmp (o
->name
, "if_marked") == 0)
2470 for (fli
= flp
; fli
; fli
= fli
->next
)
2473 if (! fli
->started_p
)
2477 oprintf (f
, "const struct ggc_root_tab gt_ggc_r_");
2478 put_mangled_filename (f
, v
->line
.file
);
2479 oprintf (f
, "[] = {\n");
2482 write_gc_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2485 finish_root_table (flp
, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2488 for (v
= variables
; v
; v
= v
->next
)
2490 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2495 for (o
= v
->opt
; o
; o
= o
->next
)
2496 if (strcmp (o
->name
, "deletable") == 0)
2498 else if (strcmp (o
->name
, "if_marked") == 0)
2504 for (fli
= flp
; fli
; fli
= fli
->next
)
2507 if (! fli
->started_p
)
2511 oprintf (f
, "const struct ggc_root_tab gt_ggc_rd_");
2512 put_mangled_filename (f
, v
->line
.file
);
2513 oprintf (f
, "[] = {\n");
2516 oprintf (f
, " { &%s, 1, sizeof (%s), NULL },\n",
2520 finish_root_table (flp
, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2521 "gt_ggc_deletable_rtab");
2523 for (v
= variables
; v
; v
= v
->next
)
2525 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2527 const char *if_marked
= NULL
;
2531 for (o
= v
->opt
; o
; o
= o
->next
)
2532 if (strcmp (o
->name
, "length") == 0)
2534 else if (strcmp (o
->name
, "if_marked") == 0)
2535 if_marked
= (const char *) o
->info
;
2537 if (if_marked
== NULL
)
2540 if (v
->type
->kind
!= TYPE_POINTER
2541 || v
->type
->u
.p
->kind
!= TYPE_PARAM_STRUCT
2542 || v
->type
->u
.p
->u
.param_struct
.stru
!= find_structure ("htab", 0))
2544 error_at_line (&v
->line
, "if_marked option used but not hash table");
2548 for (fli
= flp
; fli
; fli
= fli
->next
)
2551 if (! fli
->started_p
)
2555 oprintf (f
, "const struct ggc_cache_tab gt_ggc_rc_");
2556 put_mangled_filename (f
, v
->line
.file
);
2557 oprintf (f
, "[] = {\n");
2560 write_gc_root (f
, v
, v
->type
->u
.p
->u
.param_struct
.param
[0],
2561 v
->name
, length_p
, &v
->line
, if_marked
);
2564 finish_root_table (flp
, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2565 "gt_ggc_cache_rtab");
2569 extern int main
PARAMS ((int argc
, char **argv
));
2572 int argc ATTRIBUTE_UNUSED
;
2573 char **argv ATTRIBUTE_UNUSED
;
2576 static struct fileloc pos
= { __FILE__
, __LINE__
};
2581 srcdir_len
= strlen (srcdir
);
2583 do_scalar_typedef ("CUMULATIVE_ARGS", &pos
);
2584 do_scalar_typedef ("REAL_VALUE_TYPE", &pos
);
2585 do_scalar_typedef ("uint8", &pos
);
2586 do_scalar_typedef ("jword", &pos
);
2587 do_scalar_typedef ("JCF_u2", &pos
);
2589 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
2592 do_typedef ("HARD_REG_SET", create_array (
2593 create_scalar_type ("unsigned long", strlen ("unsigned long")),
2596 for (i
= 0; i
< NUM_GT_FILES
; i
++)
2599 /* Omit if already seen. */
2600 for (j
= 0; j
< i
; j
++)
2602 if (!strcmp (all_files
[i
], all_files
[j
]))
2609 parse_file (all_files
[i
]);
2615 set_gc_used (variables
);
2618 write_enum_defn (structures
, param_structs
);
2619 write_gc_types (structures
, param_structs
);
2620 write_gc_roots (variables
);
2622 close_output_files ();
2624 return (hit_error
!= 0);