1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004 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"
32 /* Nonzero iff an error has occurred. */
33 static int hit_error
= 0;
35 static void gen_rtx_next (void);
36 static void write_rtx_next (void);
37 static void open_base_files (void);
38 static void close_output_files (void);
40 /* Report an error at POS, printing MSG. */
43 error_at_line (struct fileloc
*pos
, const char *msg
, ...)
49 fprintf (stderr
, "%s:%d: ", pos
->file
, pos
->line
);
50 vfprintf (stderr
, msg
, ap
);
57 /* vasprintf, but produces fatal message on out-of-memory. */
59 xvasprintf (char **result
, const char *format
, va_list args
)
61 int ret
= vasprintf (result
, format
, args
);
62 if (*result
== NULL
|| ret
< 0)
64 fputs ("gengtype: out of memory", stderr
);
70 /* Wrapper for xvasprintf. */
72 xasprintf (const char *format
, ...)
77 va_start (ap
, format
);
78 xvasprintf (&result
, format
, ap
);
83 /* The one and only TYPE_STRING. */
85 struct type string_type
= {
86 TYPE_STRING
, NULL
, NULL
, GC_USED
, {0}
89 /* Lists of various things. */
91 static pair_p typedefs
;
92 static type_p structures
;
93 static type_p param_structs
;
94 static pair_p variables
;
96 static void do_scalar_typedef (const char *, struct fileloc
*);
97 static type_p find_param_structure
98 (type_p t
, type_p param
[NUM_PARAM
]);
99 static type_p
adjust_field_tree_exp (type_p t
, options_p opt
);
100 static type_p
adjust_field_rtx_def (type_p t
, options_p opt
);
102 /* Define S as a typedef to T at POS. */
105 do_typedef (const char *s
, type_p t
, struct fileloc
*pos
)
109 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
110 if (strcmp (p
->name
, s
) == 0)
114 error_at_line (pos
, "type `%s' previously defined", s
);
115 error_at_line (&p
->line
, "previously defined here");
120 p
= xmalloc (sizeof (struct pair
));
128 /* Define S as a typename of a scalar. */
131 do_scalar_typedef (const char *s
, struct fileloc
*pos
)
133 do_typedef (s
, create_scalar_type (s
, strlen (s
)), pos
);
136 /* Return the type previously defined for S. Use POS to report errors. */
139 resolve_typedef (const char *s
, struct fileloc
*pos
)
142 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
143 if (strcmp (p
->name
, s
) == 0)
145 error_at_line (pos
, "unidentified type `%s'", s
);
146 return create_scalar_type ("char", 4);
149 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
150 at POS with fields FIELDS and options O. */
153 new_structure (const char *name
, int isunion
, struct fileloc
*pos
,
154 pair_p fields
, options_p o
)
158 lang_bitmap bitmap
= get_base_file_bitmap (pos
->file
);
160 for (si
= structures
; si
!= NULL
; si
= si
->next
)
161 if (strcmp (name
, si
->u
.s
.tag
) == 0
162 && UNION_P (si
) == isunion
)
165 if (si
->kind
== TYPE_LANG_STRUCT
)
169 for (si
= ls
->u
.s
.lang_struct
; si
!= NULL
; si
= si
->next
)
170 if (si
->u
.s
.bitmap
== bitmap
)
173 else if (si
->u
.s
.line
.file
!= NULL
&& si
->u
.s
.bitmap
!= bitmap
)
176 si
= xcalloc (1, sizeof (struct type
));
177 memcpy (si
, ls
, sizeof (struct type
));
178 ls
->kind
= TYPE_LANG_STRUCT
;
179 ls
->u
.s
.lang_struct
= si
;
180 ls
->u
.s
.fields
= NULL
;
182 si
->pointer_to
= NULL
;
183 si
->u
.s
.lang_struct
= ls
;
188 if (ls
!= NULL
&& s
== NULL
)
190 s
= xcalloc (1, sizeof (struct type
));
191 s
->next
= ls
->u
.s
.lang_struct
;
192 ls
->u
.s
.lang_struct
= s
;
193 s
->u
.s
.lang_struct
= ls
;
200 s
= xcalloc (1, sizeof (struct type
));
201 s
->next
= structures
;
205 if (s
->u
.s
.line
.file
!= NULL
206 || (s
->u
.s
.lang_struct
&& (s
->u
.s
.lang_struct
->u
.s
.bitmap
& bitmap
)))
208 error_at_line (pos
, "duplicate structure definition");
209 error_at_line (&s
->u
.s
.line
, "previous definition here");
212 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
215 s
->u
.s
.fields
= fields
;
217 s
->u
.s
.bitmap
= bitmap
;
218 if (s
->u
.s
.lang_struct
)
219 s
->u
.s
.lang_struct
->u
.s
.bitmap
|= bitmap
;
222 /* Return the previously-defined structure with tag NAME (or a union
223 iff ISUNION is nonzero), or a new empty structure or union if none
224 was defined previously. */
227 find_structure (const char *name
, int isunion
)
231 for (s
= structures
; s
!= NULL
; s
= s
->next
)
232 if (strcmp (name
, s
->u
.s
.tag
) == 0
233 && UNION_P (s
) == isunion
)
236 s
= xcalloc (1, sizeof (struct type
));
237 s
->next
= structures
;
239 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
245 /* Return the previously-defined parameterized structure for structure
246 T and parameters PARAM, or a new parameterized empty structure or
247 union if none was defined previously. */
250 find_param_structure (type_p t
, type_p param
[NUM_PARAM
])
254 for (res
= param_structs
; res
; res
= res
->next
)
255 if (res
->u
.param_struct
.stru
== t
256 && memcmp (res
->u
.param_struct
.param
, param
,
257 sizeof (type_p
) * NUM_PARAM
) == 0)
261 res
= xcalloc (1, sizeof (*res
));
262 res
->kind
= TYPE_PARAM_STRUCT
;
263 res
->next
= param_structs
;
265 res
->u
.param_struct
.stru
= t
;
266 memcpy (res
->u
.param_struct
.param
, param
, sizeof (type_p
) * NUM_PARAM
);
271 /* Return a scalar type with name NAME. */
274 create_scalar_type (const char *name
, size_t name_len
)
276 type_p r
= xcalloc (1, sizeof (struct type
));
277 r
->kind
= TYPE_SCALAR
;
278 r
->u
.sc
= xmemdup (name
, name_len
, name_len
+ 1);
282 /* Return a pointer to T. */
285 create_pointer (type_p t
)
289 type_p r
= xcalloc (1, sizeof (struct type
));
290 r
->kind
= TYPE_POINTER
;
294 return t
->pointer_to
;
297 /* Return an array of length LEN. */
300 create_array (type_p t
, const char *len
)
304 v
= xcalloc (1, sizeof (*v
));
305 v
->kind
= TYPE_ARRAY
;
311 /* Return an options structure with name NAME and info INFO. */
313 create_option (const char *name
, void *info
)
315 options_p o
= xmalloc (sizeof (*o
));
321 /* Add a variable named S of type T with options O defined at POS,
325 note_variable (const char *s
, type_p t
, options_p o
, struct fileloc
*pos
)
328 n
= xmalloc (sizeof (*n
));
337 /* We really don't care how long a CONST_DOUBLE is. */
338 #define CONST_DOUBLE_FORMAT "ww"
339 const char * const rtx_format
[NUM_RTX_CODE
] = {
340 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
345 static int rtx_next_new
[NUM_RTX_CODE
];
347 /* Generate the contents of the rtx_next array. This really doesn't belong
348 in gengtype at all, but it's needed for adjust_field_rtx_def. */
354 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
358 rtx_next_new
[i
] = -1;
359 if (strncmp (rtx_format
[i
], "iuu", 3) == 0)
361 else if (i
== COND_EXEC
|| i
== SET
|| i
== EXPR_LIST
|| i
== INSN_LIST
)
364 for (k
= strlen (rtx_format
[i
]) - 1; k
>= 0; k
--)
365 if (rtx_format
[i
][k
] == 'e' || rtx_format
[i
][k
] == 'u')
370 /* Write out the contents of the rtx_next array. */
372 write_rtx_next (void)
374 outf_p f
= get_output_file_with_visibility (NULL
);
377 oprintf (f
, "\n/* Used to implement the RTX_NEXT macro. */\n");
378 oprintf (f
, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
379 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
380 if (rtx_next_new
[i
] == -1)
381 oprintf (f
, " 0,\n");
384 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
389 /* Handle `special("rtx_def")'. This is a special case for field
390 `fld' of struct rtx_def, which is an array of unions whose values
391 are based in a complex way on the type of RTL. */
394 adjust_field_rtx_def (type_p t
, options_p opt ATTRIBUTE_UNUSED
)
399 type_p rtx_tp
, rtvec_tp
, tree_tp
, mem_attrs_tp
, note_union_tp
, scalar_tp
;
400 type_p bitmap_tp
, basic_block_tp
, reg_attrs_tp
;
402 static const char * const rtx_name
[NUM_RTX_CODE
] = {
403 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
408 if (t
->kind
!= TYPE_UNION
)
410 error_at_line (&lexer_line
,
411 "special `rtx_def' must be applied to a union");
415 nodot
= xmalloc (sizeof (*nodot
));
420 rtx_tp
= create_pointer (find_structure ("rtx_def", 0));
421 rtvec_tp
= create_pointer (find_structure ("rtvec_def", 0));
422 tree_tp
= create_pointer (find_structure ("tree_node", 1));
423 mem_attrs_tp
= create_pointer (find_structure ("mem_attrs", 0));
424 reg_attrs_tp
= create_pointer (find_structure ("reg_attrs", 0));
425 bitmap_tp
= create_pointer (find_structure ("bitmap_element_def", 0));
426 basic_block_tp
= create_pointer (find_structure ("basic_block_def", 0));
427 scalar_tp
= create_scalar_type ("rtunion scalar", 14);
430 pair_p note_flds
= NULL
;
433 for (c
= NOTE_INSN_BIAS
; c
<= NOTE_INSN_MAX
; c
++)
435 pair_p old_note_flds
= note_flds
;
437 note_flds
= xmalloc (sizeof (*note_flds
));
438 note_flds
->line
.file
= __FILE__
;
439 note_flds
->line
.line
= __LINE__
;
440 note_flds
->opt
= xmalloc (sizeof (*note_flds
->opt
));
441 note_flds
->opt
->next
= nodot
;
442 note_flds
->opt
->name
= "tag";
443 note_flds
->opt
->info
= xasprintf ("%d", c
);
444 note_flds
->next
= old_note_flds
;
448 /* NOTE_INSN_MAX is used as the default field for line
451 note_flds
->opt
->name
= "default";
452 note_flds
->name
= "rtstr";
453 note_flds
->type
= &string_type
;
456 case NOTE_INSN_BLOCK_BEG
:
457 case NOTE_INSN_BLOCK_END
:
458 note_flds
->name
= "rttree";
459 note_flds
->type
= tree_tp
;
462 case NOTE_INSN_EXPECTED_VALUE
:
463 case NOTE_INSN_VAR_LOCATION
:
464 note_flds
->name
= "rtx";
465 note_flds
->type
= rtx_tp
;
469 note_flds
->name
= "rtint";
470 note_flds
->type
= scalar_tp
;
474 new_structure ("rtx_def_note_subunion", 1, &lexer_line
, note_flds
, NULL
);
477 note_union_tp
= find_structure ("rtx_def_note_subunion", 1);
479 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
481 pair_p old_flds
= flds
;
482 pair_p subfields
= NULL
;
483 size_t aindex
, nmindex
;
487 for (aindex
= 0; aindex
< strlen (rtx_format
[i
]); aindex
++)
489 pair_p old_subf
= subfields
;
493 switch (rtx_format
[i
][aindex
])
504 if (i
== MEM
&& aindex
== 1)
505 t
= mem_attrs_tp
, subname
= "rtmem";
506 else if (i
== JUMP_INSN
&& aindex
== 9)
507 t
= rtx_tp
, subname
= "rtx";
508 else if (i
== CODE_LABEL
&& aindex
== 4)
509 t
= scalar_tp
, subname
= "rtint";
510 else if (i
== CODE_LABEL
&& aindex
== 5)
511 t
= rtx_tp
, subname
= "rtx";
512 else if (i
== LABEL_REF
513 && (aindex
== 1 || aindex
== 2))
514 t
= rtx_tp
, subname
= "rtx";
515 else if (i
== NOTE
&& aindex
== 4)
516 t
= note_union_tp
, subname
= "";
517 else if (i
== NOTE
&& aindex
>= 7)
518 t
= scalar_tp
, subname
= "rtint";
519 else if (i
== ADDR_DIFF_VEC
&& aindex
== 4)
520 t
= scalar_tp
, subname
= "rtint";
521 else if (i
== VALUE
&& aindex
== 0)
522 t
= scalar_tp
, subname
= "rtint";
523 else if (i
== REG
&& aindex
== 1)
524 t
= scalar_tp
, subname
= "rtint";
525 else if (i
== REG
&& aindex
== 2)
526 t
= reg_attrs_tp
, subname
= "rtreg";
527 else if (i
== SCRATCH
&& aindex
== 0)
528 t
= scalar_tp
, subname
= "rtint";
529 else if (i
== SYMBOL_REF
&& aindex
== 1)
530 t
= scalar_tp
, subname
= "rtint";
531 else if (i
== SYMBOL_REF
&& aindex
== 2)
532 t
= tree_tp
, subname
= "rttree";
533 else if (i
== BARRIER
&& aindex
>= 3)
534 t
= scalar_tp
, subname
= "rtint";
537 error_at_line (&lexer_line
,
538 "rtx type `%s' has `0' in position %lu, can't handle",
539 rtx_name
[i
], (unsigned long) aindex
);
580 error_at_line (&lexer_line
,
581 "rtx type `%s' has `%c' in position %lu, can't handle",
582 rtx_name
[i
], rtx_format
[i
][aindex
],
583 (unsigned long)aindex
);
589 subfields
= xmalloc (sizeof (*subfields
));
590 subfields
->next
= old_subf
;
592 subfields
->name
= xasprintf (".fld[%lu].%s", (unsigned long)aindex
,
594 subfields
->line
.file
= __FILE__
;
595 subfields
->line
.line
= __LINE__
;
596 if (t
== note_union_tp
)
598 subfields
->opt
= xmalloc (sizeof (*subfields
->opt
));
599 subfields
->opt
->next
= nodot
;
600 subfields
->opt
->name
= "desc";
601 subfields
->opt
->info
= "NOTE_LINE_NUMBER (&%0)";
603 else if (t
== basic_block_tp
)
605 /* We don't presently GC basic block structures... */
606 subfields
->opt
= xmalloc (sizeof (*subfields
->opt
));
607 subfields
->opt
->next
= nodot
;
608 subfields
->opt
->name
= "skip";
609 subfields
->opt
->info
= NULL
;
612 subfields
->opt
= nodot
;
615 flds
= xmalloc (sizeof (*flds
));
616 flds
->next
= old_flds
;
618 sname
= xasprintf ("rtx_def_%s", rtx_name
[i
]);
619 new_structure (sname
, 0, &lexer_line
, subfields
, NULL
);
620 flds
->type
= find_structure (sname
, 0);
621 flds
->line
.file
= __FILE__
;
622 flds
->line
.line
= __LINE__
;
623 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
624 flds
->opt
->next
= nodot
;
625 flds
->opt
->name
= "tag";
626 ftag
= xstrdup (rtx_name
[i
]);
627 for (nmindex
= 0; nmindex
< strlen (ftag
); nmindex
++)
628 ftag
[nmindex
] = TOUPPER (ftag
[nmindex
]);
629 flds
->opt
->info
= ftag
;
632 new_structure ("rtx_def_subunion", 1, &lexer_line
, flds
, nodot
);
633 return find_structure ("rtx_def_subunion", 1);
636 /* Handle `special("tree_exp")'. This is a special case for
637 field `operands' of struct tree_exp, which although it claims to contain
638 pointers to trees, actually sometimes contains pointers to RTL too.
639 Passed T, the old type of the field, and OPT its options. Returns
640 a new type for the field. */
643 adjust_field_tree_exp (type_p t
, options_p opt ATTRIBUTE_UNUSED
)
648 static const struct {
653 { "GOTO_SUBROUTINE_EXPR", 0, 2 },
654 { "WITH_CLEANUP_EXPR", 2, 1 },
657 if (t
->kind
!= TYPE_ARRAY
)
659 error_at_line (&lexer_line
,
660 "special `tree_exp' must be applied to an array");
664 nodot
= xmalloc (sizeof (*nodot
));
669 flds
= xmalloc (sizeof (*flds
));
673 flds
->line
.file
= __FILE__
;
674 flds
->line
.line
= __LINE__
;
675 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
676 flds
->opt
->next
= nodot
;
677 flds
->opt
->name
= "length";
678 flds
->opt
->info
= "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
680 options_p oldopt
= flds
->opt
;
681 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
682 flds
->opt
->next
= oldopt
;
683 flds
->opt
->name
= "default";
684 flds
->opt
->info
= "";
687 for (i
= 0; i
< ARRAY_SIZE (data
); i
++)
689 pair_p old_flds
= flds
;
690 pair_p subfields
= NULL
;
695 r_index
< data
[i
].first_rtl
+ data
[i
].num_rtl
;
698 pair_p old_subf
= subfields
;
699 subfields
= xmalloc (sizeof (*subfields
));
700 subfields
->next
= old_subf
;
701 subfields
->name
= xasprintf ("[%d]", r_index
);
702 if (r_index
< data
[i
].first_rtl
)
703 subfields
->type
= t
->u
.a
.p
;
705 subfields
->type
= create_pointer (find_structure ("rtx_def", 0));
706 subfields
->line
.file
= __FILE__
;
707 subfields
->line
.line
= __LINE__
;
708 subfields
->opt
= nodot
;
711 flds
= xmalloc (sizeof (*flds
));
712 flds
->next
= old_flds
;
714 sname
= xasprintf ("tree_exp_%s", data
[i
].name
);
715 new_structure (sname
, 0, &lexer_line
, subfields
, NULL
);
716 flds
->type
= find_structure (sname
, 0);
717 flds
->line
.file
= __FILE__
;
718 flds
->line
.line
= __LINE__
;
719 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
720 flds
->opt
->next
= nodot
;
721 flds
->opt
->name
= "tag";
722 flds
->opt
->info
= data
[i
].name
;
725 new_structure ("tree_exp_subunion", 1, &lexer_line
, flds
, nodot
);
726 return find_structure ("tree_exp_subunion", 1);
729 /* Perform any special processing on a type T, about to become the type
730 of a field. Return the appropriate type for the field.
732 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
733 - Similarly for arrays of pointer-to-char;
734 - Converts structures for which a parameter is provided to
736 - Handles "special" options.
740 adjust_field_type (type_p t
, options_p opt
)
743 const int pointer_p
= t
->kind
== TYPE_POINTER
;
744 type_p params
[NUM_PARAM
];
748 for (i
= 0; i
< NUM_PARAM
; i
++)
751 for (; opt
; opt
= opt
->next
)
752 if (strcmp (opt
->name
, "length") == 0)
754 else if (strcmp (opt
->name
, "param_is") == 0
755 || (strncmp (opt
->name
, "param", 5) == 0
756 && ISDIGIT (opt
->name
[5])
757 && strcmp (opt
->name
+ 6, "_is") == 0))
759 int num
= ISDIGIT (opt
->name
[5]) ? opt
->name
[5] - '0' : 0;
761 if (! UNION_OR_STRUCT_P (t
)
762 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
764 error_at_line (&lexer_line
,
765 "option `%s' may only be applied to structures or structure pointers",
771 if (params
[num
] != NULL
)
772 error_at_line (&lexer_line
, "duplicate `%s' option", opt
->name
);
773 if (! ISDIGIT (opt
->name
[5]))
774 params
[num
] = create_pointer ((type_p
) opt
->info
);
776 params
[num
] = (type_p
) opt
->info
;
778 else if (strcmp (opt
->name
, "special") == 0)
780 const char *special_name
= (const char *)opt
->info
;
781 if (strcmp (special_name
, "tree_exp") == 0)
782 t
= adjust_field_tree_exp (t
, opt
);
783 else if (strcmp (special_name
, "rtx_def") == 0)
784 t
= adjust_field_rtx_def (t
, opt
);
786 error_at_line (&lexer_line
, "unknown special `%s'", special_name
);
795 realt
= find_param_structure (t
, params
);
796 t
= pointer_p
? create_pointer (realt
) : realt
;
801 && t
->u
.p
->kind
== TYPE_SCALAR
802 && (strcmp (t
->u
.p
->u
.sc
, "char") == 0
803 || strcmp (t
->u
.p
->u
.sc
, "unsigned char") == 0))
805 if (t
->kind
== TYPE_ARRAY
&& t
->u
.a
.p
->kind
== TYPE_POINTER
806 && t
->u
.a
.p
->u
.p
->kind
== TYPE_SCALAR
807 && (strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "char") == 0
808 || strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "unsigned char") == 0))
809 return create_array (&string_type
, t
->u
.a
.len
);
814 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
815 and information about the correspondence between token types and fields
816 in TYPEINFO. POS is used for error messages. */
819 note_yacc_type (options_p o
, pair_p fields
, pair_p typeinfo
,
825 for (p
= typeinfo
; p
; p
= p
->next
)
832 if (p
->type
== (type_p
) 1)
837 for (pp
= typeinfo
; pp
; pp
= pp
->next
)
838 if (pp
->type
!= (type_p
) 1
839 && strcmp (pp
->opt
->info
, p
->opt
->info
) == 0)
848 for (m
= fields
; m
; m
= m
->next
)
849 if (strcmp (m
->name
, p
->name
) == 0)
853 error_at_line (&p
->line
,
854 "couldn't match fieldname `%s'", p
->name
);
865 || p
->type
== (type_p
) 1)
871 new_structure ("yy_union", 1, pos
, typeinfo
, o
);
872 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos
);
875 static void process_gc_options (options_p
, enum gc_used_enum
,
876 int *, int *, int *, type_p
*);
877 static void set_gc_used_type (type_p
, enum gc_used_enum
, type_p
*);
878 static void set_gc_used (pair_p
);
880 /* Handle OPT for set_gc_used_type. */
883 process_gc_options (options_p opt
, enum gc_used_enum level
, int *maybe_undef
,
884 int *pass_param
, int *length
, type_p
*nested_ptr
)
887 for (o
= opt
; o
; o
= o
->next
)
888 if (strcmp (o
->name
, "ptr_alias") == 0 && level
== GC_POINTED_TO
)
889 set_gc_used_type ((type_p
) o
->info
, GC_POINTED_TO
, NULL
);
890 else if (strcmp (o
->name
, "maybe_undef") == 0)
892 else if (strcmp (o
->name
, "use_params") == 0)
894 else if (strcmp (o
->name
, "length") == 0)
896 else if (strcmp (o
->name
, "nested_ptr") == 0)
897 *nested_ptr
= ((const struct nested_ptr_data
*) o
->info
)->type
;
900 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
903 set_gc_used_type (type_p t
, enum gc_used_enum level
, type_p param
[NUM_PARAM
])
905 if (t
->gc_used
>= level
)
919 process_gc_options (t
->u
.s
.opt
, level
, &dummy
, &dummy
, &dummy
,
922 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
927 type_p nested_ptr
= NULL
;
928 process_gc_options (f
->opt
, level
, &maybe_undef
, &pass_param
,
929 &length
, &nested_ptr
);
931 if (nested_ptr
&& f
->type
->kind
== TYPE_POINTER
)
932 set_gc_used_type (nested_ptr
, GC_POINTED_TO
,
933 pass_param
? param
: NULL
);
934 else if (length
&& f
->type
->kind
== TYPE_POINTER
)
935 set_gc_used_type (f
->type
->u
.p
, GC_USED
, NULL
);
936 else if (maybe_undef
&& f
->type
->kind
== TYPE_POINTER
)
937 set_gc_used_type (f
->type
->u
.p
, GC_MAYBE_POINTED_TO
, NULL
);
938 else if (pass_param
&& f
->type
->kind
== TYPE_POINTER
&& param
)
939 set_gc_used_type (find_param_structure (f
->type
->u
.p
, param
),
940 GC_POINTED_TO
, NULL
);
942 set_gc_used_type (f
->type
, GC_USED
, pass_param
? param
: NULL
);
948 set_gc_used_type (t
->u
.p
, GC_POINTED_TO
, NULL
);
952 set_gc_used_type (t
->u
.a
.p
, GC_USED
, param
);
955 case TYPE_LANG_STRUCT
:
956 for (t
= t
->u
.s
.lang_struct
; t
; t
= t
->next
)
957 set_gc_used_type (t
, level
, param
);
960 case TYPE_PARAM_STRUCT
:
963 for (i
= 0; i
< NUM_PARAM
; i
++)
964 if (t
->u
.param_struct
.param
[i
] != 0)
965 set_gc_used_type (t
->u
.param_struct
.param
[i
], GC_USED
, NULL
);
967 if (t
->u
.param_struct
.stru
->gc_used
== GC_POINTED_TO
)
968 level
= GC_POINTED_TO
;
971 t
->u
.param_struct
.stru
->gc_used
= GC_UNUSED
;
972 set_gc_used_type (t
->u
.param_struct
.stru
, level
,
973 t
->u
.param_struct
.param
);
981 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
984 set_gc_used (pair_p variables
)
987 for (p
= variables
; p
; p
= p
->next
)
988 set_gc_used_type (p
->type
, GC_USED
, NULL
);
991 /* File mapping routines. For each input file, there is one output .c file
992 (but some output files have many input files), and there is one .h file
993 for the whole build. */
995 /* The list of output files. */
996 static outf_p output_files
;
998 /* The output header file that is included into pretty much every
1000 static outf_p header_file
;
1002 /* Number of files specified in gtfiles. */
1003 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1005 /* Number of files in the language files array. */
1006 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1008 /* Length of srcdir name. */
1009 static int srcdir_len
= 0;
1011 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1012 outf_p base_files
[NUM_BASE_FILES
];
1014 static outf_p
create_file (const char *, const char *);
1015 static const char * get_file_basename (const char *);
1017 /* Create and return an outf_p for a new file for NAME, to be called
1021 create_file (const char *name
, const char *oname
)
1023 static const char *const hdr
[] = {
1024 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
1026 "This file is part of GCC.\n",
1028 "GCC is free software; you can redistribute it and/or modify it under\n",
1029 "the terms of the GNU General Public License as published by the Free\n",
1030 "Software Foundation; either version 2, or (at your option) any later\n",
1033 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1034 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1035 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1036 "for more details.\n",
1038 "You should have received a copy of the GNU General Public License\n",
1039 "along with GCC; see the file COPYING. If not, write to the Free\n",
1040 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
1041 "02111-1307, USA. */\n",
1043 "/* This file is machine generated. Do not edit. */\n"
1048 f
= xcalloc (sizeof (*f
), 1);
1049 f
->next
= output_files
;
1053 oprintf (f
, "/* Type information for %s.\n", name
);
1054 for (i
= 0; i
< ARRAY_SIZE (hdr
); i
++)
1055 oprintf (f
, "%s", hdr
[i
]);
1059 /* Print, like fprintf, to O. */
1061 oprintf (outf_p o
, const char *format
, ...)
1067 va_start (ap
, format
);
1068 slength
= xvasprintf (&s
, format
, ap
);
1070 if (o
->bufused
+ slength
> o
->buflength
)
1072 size_t new_len
= o
->buflength
;
1077 } while (o
->bufused
+ slength
>= new_len
);
1078 o
->buf
= xrealloc (o
->buf
, new_len
);
1079 o
->buflength
= new_len
;
1081 memcpy (o
->buf
+ o
->bufused
, s
, slength
);
1082 o
->bufused
+= slength
;
1087 /* Open the global header file and the language-specific header files. */
1090 open_base_files (void)
1094 header_file
= create_file ("GCC", "gtype-desc.h");
1096 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1097 base_files
[i
] = create_file (lang_dir_names
[i
],
1098 xasprintf ("gtype-%s.h", lang_dir_names
[i
]));
1100 /* gtype-desc.c is a little special, so we create it here. */
1102 /* The order of files here matters very much. */
1103 static const char *const ifiles
[] = {
1104 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1105 "hashtab.h", "splay-tree.h", "bitmap.h", "input.h", "tree.h", "rtl.h",
1106 "function.h", "insn-config.h", "expr.h", "hard-reg-set.h",
1107 "basic-block.h", "cselib.h", "insn-addr.h", "optabs.h",
1108 "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1109 "tree-alias-type.h", "tree-flow.h", "reload.h",
1114 const char *const *ifp
;
1115 outf_p gtype_desc_c
;
1117 gtype_desc_c
= create_file ("GCC", "gtype-desc.c");
1118 for (ifp
= ifiles
; *ifp
; ifp
++)
1119 oprintf (gtype_desc_c
, "#include \"%s\"\n", *ifp
);
1123 /* Determine the pathname to F relative to $(srcdir). */
1126 get_file_basename (const char *f
)
1128 const char *basename
;
1131 basename
= strrchr (f
, '/');
1138 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1144 s1
= basename
- strlen (lang_dir_names
[i
]) - 1;
1145 s2
= lang_dir_names
[i
];
1148 if (l1
>= l2
&& !memcmp (s1
, s2
, l2
))
1151 if ((basename
- f
- 1) != srcdir_len
)
1152 abort (); /* Match is wrong - should be preceded by $srcdir. */
1160 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1161 INPUT_FILE is used by <lang>.
1163 This function should be written to assume that a file _is_ used
1164 if the situation is unclear. If it wrongly assumes a file _is_ used,
1165 a linker error will result. If it wrongly assumes a file _is not_ used,
1166 some GC roots may be missed, which is a much harder-to-debug problem. */
1169 get_base_file_bitmap (const char *input_file
)
1171 const char *basename
= get_file_basename (input_file
);
1172 const char *slashpos
= strchr (basename
, '/');
1180 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1181 if ((size_t)(slashpos
- basename
) == strlen (lang_dir_names
[i
])
1182 && memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0)
1184 /* It's in a language directory, set that language. */
1189 abort (); /* Should have found the language. */
1192 /* If it's in any config-lang.in, then set for the languages
1197 for (j
= 0; j
< NUM_LANG_FILES
; j
++)
1199 if (!strcmp(input_file
, lang_files
[j
]))
1201 for (k
= 0; k
< NUM_BASE_FILES
; k
++)
1203 if (!strcmp(lang_dir_names
[k
], langs_for_lang_files
[j
]))
1209 /* Otherwise, set all languages. */
1211 bitmap
= (1 << NUM_BASE_FILES
) - 1;
1216 /* An output file, suitable for definitions, that can see declarations
1217 made in INPUT_FILE and is linked into every language that uses
1221 get_output_file_with_visibility (const char *input_file
)
1225 const char *basename
;
1226 const char *for_name
;
1227 const char *output_name
;
1229 /* This can happen when we need a file with visibility on a
1230 structure that we've never seen. We have to just hope that it's
1231 globally visible. */
1232 if (input_file
== NULL
)
1233 input_file
= "system.h";
1235 /* Determine the output file name. */
1236 basename
= get_file_basename (input_file
);
1238 len
= strlen (basename
);
1239 if ((len
> 2 && memcmp (basename
+len
-2, ".c", 2) == 0)
1240 || (len
> 2 && memcmp (basename
+len
-2, ".y", 2) == 0)
1241 || (len
> 3 && memcmp (basename
+len
-3, ".in", 3) == 0))
1245 output_name
= s
= xasprintf ("gt-%s", basename
);
1246 for (; *s
!= '.'; s
++)
1247 if (! ISALNUM (*s
) && *s
!= '-')
1249 memcpy (s
, ".h", sizeof (".h"));
1250 for_name
= basename
;
1252 else if (strcmp (basename
, "c-common.h") == 0)
1253 output_name
= "gt-c-common.h", for_name
= "c-common.c";
1254 else if (strcmp (basename
, "c-tree.h") == 0)
1255 output_name
= "gt-c-decl.h", for_name
= "c-decl.c";
1260 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1261 if (memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0
1262 && basename
[strlen(lang_dir_names
[i
])] == '/')
1263 return base_files
[i
];
1265 output_name
= "gtype-desc.c";
1269 /* Look through to see if we've ever seen this output filename before. */
1270 for (r
= output_files
; r
; r
= r
->next
)
1271 if (strcmp (r
->name
, output_name
) == 0)
1274 /* If not, create it. */
1275 r
= create_file (for_name
, output_name
);
1280 /* The name of an output file, suitable for definitions, that can see
1281 declarations made in INPUT_FILE and is linked into every language
1282 that uses INPUT_FILE. */
1285 get_output_file_name (const char *input_file
)
1287 return get_output_file_with_visibility (input_file
)->name
;
1290 /* Copy the output to its final destination,
1291 but don't unnecessarily change modification times. */
1294 close_output_files (void)
1298 for (of
= output_files
; of
; of
= of
->next
)
1302 newfile
= fopen (of
->name
, "r");
1303 if (newfile
!= NULL
)
1308 for (i
= 0; i
< of
->bufused
; i
++)
1311 ch
= fgetc (newfile
);
1312 if (ch
== EOF
|| ch
!= (unsigned char) of
->buf
[i
])
1315 no_write_p
= i
== of
->bufused
&& fgetc (newfile
) == EOF
;
1322 newfile
= fopen (of
->name
, "w");
1323 if (newfile
== NULL
)
1325 perror ("opening output file");
1328 if (fwrite (of
->buf
, 1, of
->bufused
, newfile
) != of
->bufused
)
1330 perror ("writing output file");
1333 if (fclose (newfile
) != 0)
1335 perror ("closing output file");
1348 struct walk_type_data
;
1350 /* For scalars and strings, given the item in 'val'.
1351 For structures, given a pointer to the item in 'val'.
1352 For misc. pointers, given the item in 'val'.
1354 typedef void (*process_field_fn
)
1355 (type_p f
, const struct walk_type_data
*p
);
1356 typedef void (*func_name_fn
)
1357 (type_p s
, const struct walk_type_data
*p
);
1359 /* Parameters for write_types. */
1361 struct write_types_data
1364 const char *param_prefix
;
1365 const char *subfield_marker_routine
;
1366 const char *marker_routine
;
1367 const char *reorder_note_routine
;
1368 const char *comment
;
1371 static void output_escaped_param (struct walk_type_data
*d
,
1372 const char *, const char *);
1373 static void output_mangled_typename (outf_p
, type_p
);
1374 static void walk_type (type_p t
, struct walk_type_data
*d
);
1375 static void write_func_for_structure
1376 (type_p orig_s
, type_p s
, type_p
* param
,
1377 const struct write_types_data
*wtd
);
1378 static void write_types_process_field
1379 (type_p f
, const struct walk_type_data
*d
);
1380 static void write_types (type_p structures
,
1381 type_p param_structs
,
1382 const struct write_types_data
*wtd
);
1383 static void write_types_local_process_field
1384 (type_p f
, const struct walk_type_data
*d
);
1385 static void write_local_func_for_structure
1386 (type_p orig_s
, type_p s
, type_p
* param
);
1387 static void write_local (type_p structures
,
1388 type_p param_structs
);
1389 static void write_enum_defn (type_p structures
, type_p param_structs
);
1390 static int contains_scalar_p (type_p t
);
1391 static void put_mangled_filename (outf_p
, const char *);
1392 static void finish_root_table (struct flist
*flp
, const char *pfx
,
1393 const char *tname
, const char *lastname
,
1395 static void write_root (outf_p
, pair_p
, type_p
, const char *, int,
1396 struct fileloc
*, const char *);
1397 static void write_array (outf_p f
, pair_p v
,
1398 const struct write_types_data
*wtd
);
1399 static void write_roots (pair_p
);
1401 /* Parameters for walk_type. */
1403 struct walk_type_data
1405 process_field_fn process_field
;
1410 const char *prev_val
[4];
1413 struct fileloc
*line
;
1418 const char *reorder_fn
;
1420 bool fn_wants_lvalue
;
1423 /* Print a mangled name representing T to OF. */
1426 output_mangled_typename (outf_p of
, type_p t
)
1430 else switch (t
->kind
)
1434 output_mangled_typename (of
, t
->u
.p
);
1444 case TYPE_LANG_STRUCT
:
1445 oprintf (of
, "%lu%s", (unsigned long) strlen (t
->u
.s
.tag
), t
->u
.s
.tag
);
1447 case TYPE_PARAM_STRUCT
:
1450 for (i
= 0; i
< NUM_PARAM
; i
++)
1451 if (t
->u
.param_struct
.param
[i
] != NULL
)
1452 output_mangled_typename (of
, t
->u
.param_struct
.param
[i
]);
1453 output_mangled_typename (of
, t
->u
.param_struct
.stru
);
1461 /* Print PARAM to D->OF processing escapes. D->VAL references the
1462 current object, D->PREV_VAL the object containing the current
1463 object, ONAME is the name of the option and D->LINE is used to
1464 print error messages. */
1467 output_escaped_param (struct walk_type_data
*d
, const char *param
,
1472 for (p
= param
; *p
; p
++)
1474 oprintf (d
->of
, "%c", *p
);
1478 oprintf (d
->of
, "(%s)", d
->prev_val
[2]);
1481 oprintf (d
->of
, "(%s)", d
->prev_val
[0]);
1484 oprintf (d
->of
, "(%s)", d
->prev_val
[1]);
1488 const char *pp
= d
->val
+ strlen (d
->val
);
1489 while (pp
[-1] == ']')
1492 oprintf (d
->of
, "%s", pp
);
1496 error_at_line (d
->line
, "`%s' option contains bad escape %c%c",
1501 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1502 which is of type T. Write code to D->OF to constrain execution (at
1503 the point that D->PROCESS_FIELD is called) to the appropriate
1504 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1505 pointers to those objects. D->PREV_VAL lists the objects
1506 containing the current object, D->OPT is a list of options to
1507 apply, D->INDENT is the current indentation level, D->LINE is used
1508 to print error messages, D->BITMAP indicates which languages to
1509 print the structure for, and D->PARAM is the current parameter
1510 (from an enclosing param_is option). */
1513 walk_type (type_p t
, struct walk_type_data
*d
)
1515 const char *length
= NULL
;
1516 const char *desc
= NULL
;
1517 int maybe_undef_p
= 0;
1518 int use_param_num
= -1;
1519 int use_params_p
= 0;
1521 const struct nested_ptr_data
*nested_ptr_d
= NULL
;
1523 d
->needs_cast_p
= false;
1524 for (oo
= d
->opt
; oo
; oo
= oo
->next
)
1525 if (strcmp (oo
->name
, "length") == 0)
1526 length
= (const char *)oo
->info
;
1527 else if (strcmp (oo
->name
, "maybe_undef") == 0)
1529 else if (strncmp (oo
->name
, "use_param", 9) == 0
1530 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1531 use_param_num
= oo
->name
[9] == '\0' ? 0 : oo
->name
[9] - '0';
1532 else if (strcmp (oo
->name
, "use_params") == 0)
1534 else if (strcmp (oo
->name
, "desc") == 0)
1535 desc
= (const char *)oo
->info
;
1536 else if (strcmp (oo
->name
, "nested_ptr") == 0)
1537 nested_ptr_d
= (const struct nested_ptr_data
*) oo
->info
;
1538 else if (strcmp (oo
->name
, "dot") == 0)
1540 else if (strcmp (oo
->name
, "tag") == 0)
1542 else if (strcmp (oo
->name
, "special") == 0)
1544 else if (strcmp (oo
->name
, "skip") == 0)
1546 else if (strcmp (oo
->name
, "default") == 0)
1548 else if (strcmp (oo
->name
, "descbits") == 0)
1550 else if (strcmp (oo
->name
, "param_is") == 0)
1552 else if (strncmp (oo
->name
, "param", 5) == 0
1553 && ISDIGIT (oo
->name
[5])
1554 && strcmp (oo
->name
+ 6, "_is") == 0)
1556 else if (strcmp (oo
->name
, "chain_next") == 0)
1558 else if (strcmp (oo
->name
, "chain_prev") == 0)
1560 else if (strcmp (oo
->name
, "reorder") == 0)
1563 error_at_line (d
->line
, "unknown option `%s'\n", oo
->name
);
1570 int pointer_p
= t
->kind
== TYPE_POINTER
;
1574 if (! UNION_OR_STRUCT_P (t
))
1575 error_at_line (d
->line
, "`use_params' option on unimplemented type");
1577 t
= find_param_structure (t
, d
->param
);
1579 t
= create_pointer (t
);
1582 if (use_param_num
!= -1)
1584 if (d
->param
!= NULL
&& d
->param
[use_param_num
] != NULL
)
1586 type_p nt
= d
->param
[use_param_num
];
1588 if (t
->kind
== TYPE_ARRAY
)
1589 nt
= create_array (nt
, t
->u
.a
.len
);
1590 else if (length
!= NULL
&& t
->kind
== TYPE_POINTER
)
1591 nt
= create_pointer (nt
);
1592 d
->needs_cast_p
= (t
->kind
!= TYPE_POINTER
1593 && (nt
->kind
== TYPE_POINTER
1594 || nt
->kind
== TYPE_STRING
));
1598 error_at_line (d
->line
, "no parameter defined for `%s'",
1603 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
1605 error_at_line (d
->line
,
1606 "field `%s' has invalid option `maybe_undef_p'\n",
1615 d
->process_field (t
, d
);
1621 && t
->u
.p
->u
.s
.line
.file
== NULL
)
1623 oprintf (d
->of
, "%*sif (%s) abort();\n", d
->indent
, "", d
->val
);
1629 if (! UNION_OR_STRUCT_P (t
->u
.p
)
1630 && t
->u
.p
->kind
!= TYPE_PARAM_STRUCT
)
1632 error_at_line (d
->line
,
1633 "field `%s' is pointer to unimplemented type",
1640 const char *oldprevval2
= d
->prev_val
[2];
1642 if (! UNION_OR_STRUCT_P (nested_ptr_d
->type
))
1644 error_at_line (d
->line
,
1645 "field `%s' has invalid "
1646 "option `nested_ptr'\n",
1651 d
->prev_val
[2] = d
->val
;
1652 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1654 d
->val
= xasprintf ("x%d", d
->counter
++);
1655 oprintf (d
->of
, "%*s%s %s * %s%s =\n", d
->indent
, "",
1656 (nested_ptr_d
->type
->kind
== TYPE_UNION
1657 ? "union" : "struct"),
1658 nested_ptr_d
->type
->u
.s
.tag
,
1659 d
->fn_wants_lvalue
? "" : "const ",
1661 oprintf (d
->of
, "%*s", d
->indent
+ 2, "");
1662 output_escaped_param (d
, nested_ptr_d
->convert_from
,
1664 oprintf (d
->of
, ";\n");
1666 d
->process_field (nested_ptr_d
->type
, d
);
1668 if (d
->fn_wants_lvalue
)
1670 oprintf (d
->of
, "%*s%s = ", d
->indent
, "",
1672 d
->prev_val
[2] = d
->val
;
1673 output_escaped_param (d
, nested_ptr_d
->convert_to
,
1675 oprintf (d
->of
, ";\n");
1679 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1680 d
->val
= d
->prev_val
[2];
1681 d
->prev_val
[2] = oldprevval2
;
1684 d
->process_field (t
->u
.p
, d
);
1688 int loopcounter
= d
->counter
++;
1689 const char *oldval
= d
->val
;
1690 const char *oldprevval3
= d
->prev_val
[3];
1693 oprintf (d
->of
, "%*sif (%s != NULL) {\n", d
->indent
, "", d
->val
);
1695 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1696 oprintf (d
->of
, "%*sfor (i%d = 0; i%d < (size_t)(", d
->indent
, "",
1697 loopcounter
, loopcounter
);
1698 output_escaped_param (d
, length
, "length");
1699 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1701 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1703 d
->prev_val
[3] = oldval
;
1704 walk_type (t
->u
.p
, d
);
1707 d
->prev_val
[3] = oldprevval3
;
1710 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1711 d
->process_field(t
, d
);
1713 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1720 int loopcounter
= d
->counter
++;
1721 const char *oldval
= d
->val
;
1724 /* If it's an array of scalars, we optimize by not generating
1726 if (t
->u
.a
.p
->kind
== TYPE_SCALAR
)
1729 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1731 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1732 oprintf (d
->of
, "%*sfor (i%d = 0; i%d < (size_t)(", d
->indent
, "",
1733 loopcounter
, loopcounter
);
1735 output_escaped_param (d
, length
, "length");
1737 oprintf (d
->of
, "%s", t
->u
.a
.len
);
1738 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1740 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1742 walk_type (t
->u
.a
.p
, d
);
1747 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1749 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1757 const char *oldval
= d
->val
;
1758 const char *oldprevval1
= d
->prev_val
[1];
1759 const char *oldprevval2
= d
->prev_val
[2];
1760 const int union_p
= t
->kind
== TYPE_UNION
;
1761 int seen_default_p
= 0;
1764 if (! t
->u
.s
.line
.file
)
1765 error_at_line (d
->line
, "incomplete structure `%s'", t
->u
.s
.tag
);
1767 if ((d
->bitmap
& t
->u
.s
.bitmap
) != d
->bitmap
)
1769 error_at_line (d
->line
,
1770 "structure `%s' defined for mismatching languages",
1772 error_at_line (&t
->u
.s
.line
, "one structure defined here");
1775 /* Some things may also be defined in the structure's options. */
1776 for (o
= t
->u
.s
.opt
; o
; o
= o
->next
)
1777 if (! desc
&& strcmp (o
->name
, "desc") == 0)
1778 desc
= (const char *)o
->info
;
1780 d
->prev_val
[2] = oldval
;
1781 d
->prev_val
[1] = oldprevval2
;
1786 error_at_line (d
->line
, "missing `desc' option for union `%s'",
1790 oprintf (d
->of
, "%*sswitch (", d
->indent
, "");
1791 output_escaped_param (d
, desc
, "desc");
1792 oprintf (d
->of
, ")\n");
1794 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1796 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
1799 const char *dot
= ".";
1800 const char *tagid
= NULL
;
1803 int use_param_p
= 0;
1806 d
->reorder_fn
= NULL
;
1807 for (oo
= f
->opt
; oo
; oo
= oo
->next
)
1808 if (strcmp (oo
->name
, "dot") == 0)
1809 dot
= (const char *)oo
->info
;
1810 else if (strcmp (oo
->name
, "tag") == 0)
1811 tagid
= (const char *)oo
->info
;
1812 else if (strcmp (oo
->name
, "skip") == 0)
1814 else if (strcmp (oo
->name
, "default") == 0)
1816 else if (strcmp (oo
->name
, "reorder") == 0)
1817 d
->reorder_fn
= (const char *)oo
->info
;
1818 else if (strncmp (oo
->name
, "use_param", 9) == 0
1819 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1825 if (union_p
&& tagid
)
1827 oprintf (d
->of
, "%*scase %s:\n", d
->indent
, "", tagid
);
1830 else if (union_p
&& default_p
)
1832 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1836 else if (! union_p
&& (default_p
|| tagid
))
1837 error_at_line (d
->line
,
1838 "can't use `%s' outside a union on field `%s'",
1839 default_p
? "default" : "tag", f
->name
);
1840 else if (union_p
&& ! (default_p
|| tagid
)
1841 && f
->type
->kind
== TYPE_SCALAR
)
1844 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1845 d
->line
->file
, d
->line
->line
, f
->name
);
1848 else if (union_p
&& ! (default_p
|| tagid
))
1849 error_at_line (d
->line
,
1850 "field `%s' is missing `tag' or `default' option",
1854 d
->val
= newval
= xasprintf ("%s%s%s", oldval
, dot
, f
->name
);
1856 d
->used_length
= false;
1858 if (union_p
&& use_param_p
&& d
->param
== NULL
)
1859 oprintf (d
->of
, "%*sabort();\n", d
->indent
, "");
1861 walk_type (f
->type
, d
);
1867 oprintf (d
->of
, "%*sbreak;\n", d
->indent
, "");
1871 d
->reorder_fn
= NULL
;
1874 d
->prev_val
[1] = oldprevval1
;
1875 d
->prev_val
[2] = oldprevval2
;
1877 if (union_p
&& ! seen_default_p
)
1879 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1880 oprintf (d
->of
, "%*s break;\n", d
->indent
, "");
1884 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1890 case TYPE_LANG_STRUCT
:
1893 for (nt
= t
->u
.s
.lang_struct
; nt
; nt
= nt
->next
)
1894 if ((d
->bitmap
& nt
->u
.s
.bitmap
) == d
->bitmap
)
1897 error_at_line (d
->line
, "structure `%s' differs between languages",
1904 case TYPE_PARAM_STRUCT
:
1906 type_p
*oldparam
= d
->param
;
1908 d
->param
= t
->u
.param_struct
.param
;
1909 walk_type (t
->u
.param_struct
.stru
, d
);
1910 d
->param
= oldparam
;
1919 /* process_field routine for marking routines. */
1922 write_types_process_field (type_p f
, const struct walk_type_data
*d
)
1924 const struct write_types_data
*wtd
;
1925 const char *cast
= d
->needs_cast_p
? "(void *)" : "";
1926 wtd
= (const struct write_types_data
*) d
->cookie
;
1931 oprintf (d
->of
, "%*s%s (%s%s", d
->indent
, "",
1932 wtd
->subfield_marker_routine
, cast
, d
->val
);
1933 if (wtd
->param_prefix
)
1935 oprintf (d
->of
, ", %s", d
->prev_val
[3]);
1938 oprintf (d
->of
, ", gt_%s_", wtd
->param_prefix
);
1939 output_mangled_typename (d
->of
, d
->orig_s
);
1942 oprintf (d
->of
, ", gt_%sa_%s", wtd
->param_prefix
, d
->prev_val
[0]);
1944 oprintf (d
->of
, ");\n");
1945 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1946 oprintf (d
->of
, "%*s%s (%s%s, %s, %s);\n", d
->indent
, "",
1947 wtd
->reorder_note_routine
, cast
, d
->val
,
1948 d
->prev_val
[3], d
->reorder_fn
);
1952 if (wtd
->param_prefix
== NULL
)
1957 case TYPE_LANG_STRUCT
:
1958 case TYPE_PARAM_STRUCT
:
1959 oprintf (d
->of
, "%*sgt_%s_", d
->indent
, "", wtd
->prefix
);
1960 output_mangled_typename (d
->of
, f
);
1961 oprintf (d
->of
, " (%s%s);\n", cast
, d
->val
);
1962 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1963 oprintf (d
->of
, "%*s%s (%s%s, %s%s, %s);\n", d
->indent
, "",
1964 wtd
->reorder_note_routine
, cast
, d
->val
, cast
, d
->val
,
1976 /* For S, a structure that's part of ORIG_S, and using parameters
1977 PARAM, write out a routine that:
1978 - Takes a parameter, a void * but actually of type *S
1979 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1980 field of S or its substructures and (in some cases) things
1981 that are pointed to by S.
1985 write_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
,
1986 const struct write_types_data
*wtd
)
1988 const char *fn
= s
->u
.s
.line
.file
;
1990 const char *chain_next
= NULL
;
1991 const char *chain_prev
= NULL
;
1993 struct walk_type_data d
;
1995 /* This is a hack, and not the good kind either. */
1996 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
1997 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
1998 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
1999 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2001 memset (&d
, 0, sizeof (d
));
2002 d
.of
= get_output_file_with_visibility (fn
);
2004 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2005 if (strcmp (opt
->name
, "chain_next") == 0)
2006 chain_next
= (const char *) opt
->info
;
2007 else if (strcmp (opt
->name
, "chain_prev") == 0)
2008 chain_prev
= (const char *) opt
->info
;
2010 if (chain_prev
!= NULL
&& chain_next
== NULL
)
2011 error_at_line (&s
->u
.s
.line
, "chain_prev without chain_next");
2013 d
.process_field
= write_types_process_field
;
2017 d
.line
= &s
->u
.s
.line
;
2018 d
.bitmap
= s
->u
.s
.bitmap
;
2020 d
.prev_val
[0] = "*x";
2021 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2022 d
.prev_val
[3] = "x";
2025 oprintf (d
.of
, "\n");
2026 oprintf (d
.of
, "void\n");
2028 oprintf (d
.of
, "gt_%sx_%s", wtd
->prefix
, orig_s
->u
.s
.tag
);
2031 oprintf (d
.of
, "gt_%s_", wtd
->prefix
);
2032 output_mangled_typename (d
.of
, orig_s
);
2034 oprintf (d
.of
, " (void *x_p)\n");
2035 oprintf (d
.of
, "{\n");
2036 oprintf (d
.of
, " %s %s * %sx = (%s %s *)x_p;\n",
2037 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2038 chain_next
== NULL
? "const " : "",
2039 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2040 if (chain_next
!= NULL
)
2041 oprintf (d
.of
, " %s %s * xlimit = x;\n",
2042 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2043 if (chain_next
== NULL
)
2045 oprintf (d
.of
, " if (%s (x", wtd
->marker_routine
);
2046 if (wtd
->param_prefix
)
2048 oprintf (d
.of
, ", x, gt_%s_", wtd
->param_prefix
);
2049 output_mangled_typename (d
.of
, orig_s
);
2051 oprintf (d
.of
, "))\n");
2055 oprintf (d
.of
, " while (%s (xlimit", wtd
->marker_routine
);
2056 if (wtd
->param_prefix
)
2058 oprintf (d
.of
, ", xlimit, gt_%s_", wtd
->param_prefix
);
2059 output_mangled_typename (d
.of
, orig_s
);
2061 oprintf (d
.of
, "))\n");
2062 oprintf (d
.of
, " xlimit = (");
2063 d
.prev_val
[2] = "*xlimit";
2064 output_escaped_param (&d
, chain_next
, "chain_next");
2065 oprintf (d
.of
, ");\n");
2066 if (chain_prev
!= NULL
)
2068 oprintf (d
.of
, " if (x != xlimit)\n");
2069 oprintf (d
.of
, " for (;;)\n");
2070 oprintf (d
.of
, " {\n");
2071 oprintf (d
.of
, " %s %s * const xprev = (",
2072 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2074 d
.prev_val
[2] = "*x";
2075 output_escaped_param (&d
, chain_prev
, "chain_prev");
2076 oprintf (d
.of
, ");\n");
2077 oprintf (d
.of
, " if (xprev == NULL) break;\n");
2078 oprintf (d
.of
, " x = xprev;\n");
2079 oprintf (d
.of
, " (void) %s (xprev",
2080 wtd
->marker_routine
);
2081 if (wtd
->param_prefix
)
2083 oprintf (d
.of
, ", xprev, gt_%s_", wtd
->param_prefix
);
2084 output_mangled_typename (d
.of
, orig_s
);
2086 oprintf (d
.of
, ");\n");
2087 oprintf (d
.of
, " }\n");
2089 oprintf (d
.of
, " while (x != xlimit)\n");
2091 oprintf (d
.of
, " {\n");
2093 d
.prev_val
[2] = "*x";
2097 if (chain_next
!= NULL
)
2099 oprintf (d
.of
, " x = (");
2100 output_escaped_param (&d
, chain_next
, "chain_next");
2101 oprintf (d
.of
, ");\n");
2104 oprintf (d
.of
, " }\n");
2105 oprintf (d
.of
, "}\n");
2108 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2111 write_types (type_p structures
, type_p param_structs
,
2112 const struct write_types_data
*wtd
)
2116 oprintf (header_file
, "\n/* %s*/\n", wtd
->comment
);
2117 for (s
= structures
; s
; s
= s
->next
)
2118 if (s
->gc_used
== GC_POINTED_TO
2119 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2123 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2124 && s
->u
.s
.line
.file
== NULL
)
2127 oprintf (header_file
, "#define gt_%s_", wtd
->prefix
);
2128 output_mangled_typename (header_file
, s
);
2129 oprintf (header_file
, "(X) do { \\\n");
2130 oprintf (header_file
,
2131 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd
->prefix
,
2133 oprintf (header_file
,
2136 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2137 if (strcmp (opt
->name
, "ptr_alias") == 0)
2139 type_p t
= (type_p
) opt
->info
;
2140 if (t
->kind
== TYPE_STRUCT
2141 || t
->kind
== TYPE_UNION
2142 || t
->kind
== TYPE_LANG_STRUCT
)
2143 oprintf (header_file
,
2144 "#define gt_%sx_%s gt_%sx_%s\n",
2145 wtd
->prefix
, s
->u
.s
.tag
, wtd
->prefix
, t
->u
.s
.tag
);
2147 error_at_line (&s
->u
.s
.line
,
2148 "structure alias is not a structure");
2154 /* Declare the marker procedure only once. */
2155 oprintf (header_file
,
2156 "extern void gt_%sx_%s (void *);\n",
2157 wtd
->prefix
, s
->u
.s
.tag
);
2159 if (s
->u
.s
.line
.file
== NULL
)
2161 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2166 if (s
->kind
== TYPE_LANG_STRUCT
)
2169 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2170 write_func_for_structure (s
, ss
, NULL
, wtd
);
2173 write_func_for_structure (s
, s
, NULL
, wtd
);
2176 for (s
= param_structs
; s
; s
= s
->next
)
2177 if (s
->gc_used
== GC_POINTED_TO
)
2179 type_p
* param
= s
->u
.param_struct
.param
;
2180 type_p stru
= s
->u
.param_struct
.stru
;
2182 /* Declare the marker procedure. */
2183 oprintf (header_file
, "extern void gt_%s_", wtd
->prefix
);
2184 output_mangled_typename (header_file
, s
);
2185 oprintf (header_file
, " (void *);\n");
2187 if (stru
->u
.s
.line
.file
== NULL
)
2189 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2194 if (stru
->kind
== TYPE_LANG_STRUCT
)
2197 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2198 write_func_for_structure (s
, ss
, param
, wtd
);
2201 write_func_for_structure (s
, stru
, param
, wtd
);
2205 static const struct write_types_data ggc_wtd
=
2207 "ggc_m", NULL
, "ggc_mark", "ggc_test_and_set_mark", NULL
,
2208 "GC marker procedures. "
2211 static const struct write_types_data pch_wtd
=
2213 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2214 "gt_pch_note_reorder",
2215 "PCH type-walking procedures. "
2218 /* Write out the local pointer-walking routines. */
2220 /* process_field routine for local pointer-walking. */
2223 write_types_local_process_field (type_p f
, const struct walk_type_data
*d
)
2230 case TYPE_LANG_STRUCT
:
2231 case TYPE_PARAM_STRUCT
:
2233 oprintf (d
->of
, "%*sif ((void *)(%s) == this_obj)\n", d
->indent
, "",
2235 oprintf (d
->of
, "%*s op (&(%s), cookie);\n", d
->indent
, "", d
->val
);
2246 /* For S, a structure that's part of ORIG_S, and using parameters
2247 PARAM, write out a routine that:
2248 - Is of type gt_note_pointers
2249 - Calls PROCESS_FIELD on each field of S or its substructures.
2253 write_local_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
)
2255 const char *fn
= s
->u
.s
.line
.file
;
2257 struct walk_type_data d
;
2259 /* This is a hack, and not the good kind either. */
2260 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
2261 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
2262 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
2263 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2265 memset (&d
, 0, sizeof (d
));
2266 d
.of
= get_output_file_with_visibility (fn
);
2268 d
.process_field
= write_types_local_process_field
;
2270 d
.line
= &s
->u
.s
.line
;
2271 d
.bitmap
= s
->u
.s
.bitmap
;
2273 d
.prev_val
[0] = d
.prev_val
[2] = "*x";
2274 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2275 d
.prev_val
[3] = "x";
2277 d
.fn_wants_lvalue
= true;
2279 oprintf (d
.of
, "\n");
2280 oprintf (d
.of
, "void\n");
2281 oprintf (d
.of
, "gt_pch_p_");
2282 output_mangled_typename (d
.of
, orig_s
);
2283 oprintf (d
.of
, " (void *this_obj ATTRIBUTE_UNUSED,\n\tvoid *x_p,\n\tgt_pointer_operator op ATTRIBUTE_UNUSED,\n\tvoid *cookie ATTRIBUTE_UNUSED)\n");
2284 oprintf (d
.of
, "{\n");
2285 oprintf (d
.of
, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2286 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2287 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2290 oprintf (d
.of
, "}\n");
2293 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2296 write_local (type_p structures
, type_p param_structs
)
2300 oprintf (header_file
, "\n/* Local pointer-walking routines. */\n");
2301 for (s
= structures
; s
; s
= s
->next
)
2302 if (s
->gc_used
== GC_POINTED_TO
2303 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2307 if (s
->u
.s
.line
.file
== NULL
)
2310 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2311 if (strcmp (opt
->name
, "ptr_alias") == 0)
2313 type_p t
= (type_p
) opt
->info
;
2314 if (t
->kind
== TYPE_STRUCT
2315 || t
->kind
== TYPE_UNION
2316 || t
->kind
== TYPE_LANG_STRUCT
)
2318 oprintf (header_file
, "#define gt_pch_p_");
2319 output_mangled_typename (header_file
, s
);
2320 oprintf (header_file
, " gt_pch_p_");
2321 output_mangled_typename (header_file
, t
);
2322 oprintf (header_file
, "\n");
2325 error_at_line (&s
->u
.s
.line
,
2326 "structure alias is not a structure");
2332 /* Declare the marker procedure only once. */
2333 oprintf (header_file
, "extern void gt_pch_p_");
2334 output_mangled_typename (header_file
, s
);
2335 oprintf (header_file
,
2336 "\n (void *, void *, gt_pointer_operator, void *);\n");
2338 if (s
->kind
== TYPE_LANG_STRUCT
)
2341 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2342 write_local_func_for_structure (s
, ss
, NULL
);
2345 write_local_func_for_structure (s
, s
, NULL
);
2348 for (s
= param_structs
; s
; s
= s
->next
)
2349 if (s
->gc_used
== GC_POINTED_TO
)
2351 type_p
* param
= s
->u
.param_struct
.param
;
2352 type_p stru
= s
->u
.param_struct
.stru
;
2354 /* Declare the marker procedure. */
2355 oprintf (header_file
, "extern void gt_pch_p_");
2356 output_mangled_typename (header_file
, s
);
2357 oprintf (header_file
,
2358 "\n (void *, void *, gt_pointer_operator, void *);\n");
2360 if (stru
->u
.s
.line
.file
== NULL
)
2362 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2367 if (stru
->kind
== TYPE_LANG_STRUCT
)
2370 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2371 write_local_func_for_structure (s
, ss
, param
);
2374 write_local_func_for_structure (s
, stru
, param
);
2378 /* Write out the 'enum' definition for gt_types_enum. */
2381 write_enum_defn (type_p structures
, type_p param_structs
)
2385 oprintf (header_file
, "\n/* Enumeration of types known. */\n");
2386 oprintf (header_file
, "enum gt_types_enum {\n");
2387 for (s
= structures
; s
; s
= s
->next
)
2388 if (s
->gc_used
== GC_POINTED_TO
2389 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2391 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2392 && s
->u
.s
.line
.file
== NULL
)
2395 oprintf (header_file
, " gt_ggc_e_");
2396 output_mangled_typename (header_file
, s
);
2397 oprintf (header_file
, ", \n");
2399 for (s
= param_structs
; s
; s
= s
->next
)
2400 if (s
->gc_used
== GC_POINTED_TO
)
2402 oprintf (header_file
, " gt_e_");
2403 output_mangled_typename (header_file
, s
);
2404 oprintf (header_file
, ", \n");
2406 oprintf (header_file
, " gt_types_enum_last\n");
2407 oprintf (header_file
, "};\n");
2410 /* Might T contain any non-pointer elements? */
2413 contains_scalar_p (type_p t
)
2421 return contains_scalar_p (t
->u
.a
.p
);
2423 /* Could also check for structures that have no non-pointer
2424 fields, but there aren't enough of those to worry about. */
2429 /* Mangle FN and print it to F. */
2432 put_mangled_filename (outf_p f
, const char *fn
)
2434 const char *name
= get_output_file_name (fn
);
2435 for (; *name
!= 0; name
++)
2436 if (ISALNUM (*name
))
2437 oprintf (f
, "%c", *name
);
2439 oprintf (f
, "%c", '_');
2442 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2443 LASTNAME, and NAME are all strings to insert in various places in
2444 the resulting code. */
2447 finish_root_table (struct flist
*flp
, const char *pfx
, const char *lastname
,
2448 const char *tname
, const char *name
)
2452 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2453 if (fli2
->started_p
)
2455 oprintf (fli2
->f
, " %s\n", lastname
);
2456 oprintf (fli2
->f
, "};\n\n");
2459 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2460 if (fli2
->started_p
)
2462 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2465 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2468 oprintf (base_files
[fnum
],
2469 "extern const struct %s gt_%s_",
2471 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2472 oprintf (base_files
[fnum
], "[];\n");
2478 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2479 oprintf (base_files
[fnum
],
2480 "const struct %s * const %s[] = {\n",
2485 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2486 if (fli2
->started_p
)
2488 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2491 fli2
->started_p
= 0;
2493 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2496 oprintf (base_files
[fnum
], " gt_%s_", pfx
);
2497 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2498 oprintf (base_files
[fnum
], ",\n");
2504 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2506 oprintf (base_files
[fnum
], " NULL\n");
2507 oprintf (base_files
[fnum
], "};\n");
2512 /* Write out to F the table entry and any marker routines needed to
2513 mark NAME as TYPE. The original variable is V, at LINE.
2514 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2515 is nonzero iff we are building the root table for hash table caches. */
2518 write_root (outf_p f
, pair_p v
, type_p type
, const char *name
, int has_length
,
2519 struct fileloc
*line
, const char *if_marked
)
2526 for (fld
= type
->u
.s
.fields
; fld
; fld
= fld
->next
)
2529 const char *desc
= NULL
;
2532 for (o
= fld
->opt
; o
; o
= o
->next
)
2533 if (strcmp (o
->name
, "skip") == 0)
2535 else if (strcmp (o
->name
, "desc") == 0)
2536 desc
= (const char *)o
->info
;
2538 error_at_line (line
,
2539 "field `%s' of global `%s' has unknown option `%s'",
2540 fld
->name
, name
, o
->name
);
2544 else if (desc
&& fld
->type
->kind
== TYPE_UNION
)
2546 pair_p validf
= NULL
;
2549 for (ufld
= fld
->type
->u
.s
.fields
; ufld
; ufld
= ufld
->next
)
2551 const char *tag
= NULL
;
2554 for (oo
= ufld
->opt
; oo
; oo
= oo
->next
)
2555 if (strcmp (oo
->name
, "tag") == 0)
2556 tag
= (const char *)oo
->info
;
2557 if (tag
== NULL
|| strcmp (tag
, desc
) != 0)
2560 error_at_line (line
,
2561 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2562 name
, fld
->name
, validf
->name
,
2563 name
, fld
->name
, ufld
->name
,
2570 newname
= xasprintf ("%s.%s.%s",
2571 name
, fld
->name
, validf
->name
);
2572 write_root (f
, v
, validf
->type
, newname
, 0, line
,
2578 error_at_line (line
,
2579 "global `%s.%s' has `desc' option but is not union",
2584 newname
= xasprintf ("%s.%s", name
, fld
->name
);
2585 write_root (f
, v
, fld
->type
, newname
, 0, line
, if_marked
);
2595 newname
= xasprintf ("%s[0]", name
);
2596 write_root (f
, v
, type
->u
.a
.p
, newname
, has_length
, line
, if_marked
);
2605 oprintf (f
, " {\n");
2606 oprintf (f
, " &%s,\n", name
);
2609 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2611 oprintf (f
, " * (%s)", ap
->u
.a
.len
);
2612 else if (ap
== v
->type
)
2613 oprintf (f
, " * ARRAY_SIZE (%s)", v
->name
);
2615 oprintf (f
, " sizeof (%s", v
->name
);
2616 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2618 oprintf (f
, "),\n");
2622 if (! has_length
&& UNION_OR_STRUCT_P (tp
))
2624 oprintf (f
, " >_ggc_mx_%s,\n", tp
->u
.s
.tag
);
2625 oprintf (f
, " >_pch_nx_%s", tp
->u
.s
.tag
);
2627 else if (! has_length
&& tp
->kind
== TYPE_PARAM_STRUCT
)
2629 oprintf (f
, " >_ggc_m_");
2630 output_mangled_typename (f
, tp
);
2631 oprintf (f
, ",\n >_pch_n_");
2632 output_mangled_typename (f
, tp
);
2635 && (tp
->kind
== TYPE_POINTER
|| UNION_OR_STRUCT_P (tp
)))
2637 oprintf (f
, " >_ggc_ma_%s,\n", name
);
2638 oprintf (f
, " >_pch_na_%s", name
);
2642 error_at_line (line
,
2643 "global `%s' is pointer to unimplemented type",
2647 oprintf (f
, ",\n &%s", if_marked
);
2648 oprintf (f
, "\n },\n");
2654 oprintf (f
, " {\n");
2655 oprintf (f
, " &%s,\n", name
);
2656 oprintf (f
, " 1, \n");
2657 oprintf (f
, " sizeof (%s),\n", v
->name
);
2658 oprintf (f
, " >_ggc_m_S,\n");
2659 oprintf (f
, " (gt_pointer_walker) >_pch_n_S\n");
2660 oprintf (f
, " },\n");
2668 error_at_line (line
,
2669 "global `%s' is unimplemented type",
2674 /* This generates a routine to walk an array. */
2677 write_array (outf_p f
, pair_p v
, const struct write_types_data
*wtd
)
2679 struct walk_type_data d
;
2682 memset (&d
, 0, sizeof (d
));
2688 d
.bitmap
= get_base_file_bitmap (v
->line
.file
);
2691 d
.prev_val
[3] = prevval3
= xasprintf ("&%s", v
->name
);
2693 if (wtd
->param_prefix
)
2695 oprintf (f
, "static void gt_%sa_%s\n", wtd
->param_prefix
, v
->name
);
2697 " (void *, void *, gt_pointer_operator, void *);\n");
2698 oprintf (f
, "static void gt_%sa_%s (void *this_obj ATTRIBUTE_UNUSED,\n",
2699 wtd
->param_prefix
, v
->name
);
2700 oprintf (d
.of
, " void *x_p ATTRIBUTE_UNUSED,\n");
2701 oprintf (d
.of
, " gt_pointer_operator op ATTRIBUTE_UNUSED,\n");
2702 oprintf (d
.of
, " void *cookie ATTRIBUTE_UNUSED)\n");
2703 oprintf (d
.of
, "{\n");
2704 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2705 d
.process_field
= write_types_local_process_field
;
2706 walk_type (v
->type
, &d
);
2707 oprintf (f
, "}\n\n");
2711 oprintf (f
, "static void gt_%sa_%s (void *);\n",
2712 wtd
->prefix
, v
->name
);
2713 oprintf (f
, "static void\ngt_%sa_%s (void *x_p ATTRIBUTE_UNUSED)\n",
2714 wtd
->prefix
, v
->name
);
2716 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2717 d
.process_field
= write_types_process_field
;
2718 walk_type (v
->type
, &d
);
2720 oprintf (f
, "}\n\n");
2723 /* Output a table describing the locations and types of VARIABLES. */
2726 write_roots (pair_p variables
)
2729 struct flist
*flp
= NULL
;
2731 for (v
= variables
; v
; v
= v
->next
)
2733 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2735 const char *length
= NULL
;
2736 int deletable_p
= 0;
2739 for (o
= v
->opt
; o
; o
= o
->next
)
2740 if (strcmp (o
->name
, "length") == 0)
2741 length
= (const char *)o
->info
;
2742 else if (strcmp (o
->name
, "deletable") == 0)
2744 else if (strcmp (o
->name
, "param_is") == 0)
2746 else if (strncmp (o
->name
, "param", 5) == 0
2747 && ISDIGIT (o
->name
[5])
2748 && strcmp (o
->name
+ 6, "_is") == 0)
2750 else if (strcmp (o
->name
, "if_marked") == 0)
2753 error_at_line (&v
->line
,
2754 "global `%s' has unknown option `%s'",
2757 for (fli
= flp
; fli
; fli
= fli
->next
)
2762 fli
= xmalloc (sizeof (*fli
));
2766 fli
->name
= v
->line
.file
;
2769 oprintf (f
, "\n/* GC roots. */\n\n");
2774 && v
->type
->kind
== TYPE_POINTER
2775 && (v
->type
->u
.p
->kind
== TYPE_POINTER
2776 || v
->type
->u
.p
->kind
== TYPE_STRUCT
))
2778 write_array (f
, v
, &ggc_wtd
);
2779 write_array (f
, v
, &pch_wtd
);
2783 for (v
= variables
; v
; v
= v
->next
)
2785 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2791 for (o
= v
->opt
; o
; o
= o
->next
)
2792 if (strcmp (o
->name
, "length") == 0)
2794 else if (strcmp (o
->name
, "deletable") == 0
2795 || strcmp (o
->name
, "if_marked") == 0)
2801 for (fli
= flp
; fli
; fli
= fli
->next
)
2804 if (! fli
->started_p
)
2808 oprintf (f
, "const struct ggc_root_tab gt_ggc_r_");
2809 put_mangled_filename (f
, v
->line
.file
);
2810 oprintf (f
, "[] = {\n");
2813 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2816 finish_root_table (flp
, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2819 for (v
= variables
; v
; v
= v
->next
)
2821 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2826 for (o
= v
->opt
; o
; o
= o
->next
)
2827 if (strcmp (o
->name
, "deletable") == 0)
2829 else if (strcmp (o
->name
, "if_marked") == 0)
2835 for (fli
= flp
; fli
; fli
= fli
->next
)
2838 if (! fli
->started_p
)
2842 oprintf (f
, "const struct ggc_root_tab gt_ggc_rd_");
2843 put_mangled_filename (f
, v
->line
.file
);
2844 oprintf (f
, "[] = {\n");
2847 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2851 finish_root_table (flp
, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2852 "gt_ggc_deletable_rtab");
2854 for (v
= variables
; v
; v
= v
->next
)
2856 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2858 const char *if_marked
= NULL
;
2862 for (o
= v
->opt
; o
; o
= o
->next
)
2863 if (strcmp (o
->name
, "length") == 0)
2865 else if (strcmp (o
->name
, "if_marked") == 0)
2866 if_marked
= (const char *) o
->info
;
2868 if (if_marked
== NULL
)
2871 if (v
->type
->kind
!= TYPE_POINTER
2872 || v
->type
->u
.p
->kind
!= TYPE_PARAM_STRUCT
2873 || v
->type
->u
.p
->u
.param_struct
.stru
!= find_structure ("htab", 0))
2875 error_at_line (&v
->line
, "if_marked option used but not hash table");
2879 for (fli
= flp
; fli
; fli
= fli
->next
)
2882 if (! fli
->started_p
)
2886 oprintf (f
, "const struct ggc_cache_tab gt_ggc_rc_");
2887 put_mangled_filename (f
, v
->line
.file
);
2888 oprintf (f
, "[] = {\n");
2891 write_root (f
, v
, v
->type
->u
.p
->u
.param_struct
.param
[0],
2892 v
->name
, length_p
, &v
->line
, if_marked
);
2895 finish_root_table (flp
, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2896 "gt_ggc_cache_rtab");
2898 for (v
= variables
; v
; v
= v
->next
)
2900 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2903 int if_marked_p
= 0;
2906 for (o
= v
->opt
; o
; o
= o
->next
)
2907 if (strcmp (o
->name
, "length") == 0)
2909 else if (strcmp (o
->name
, "if_marked") == 0)
2915 for (fli
= flp
; fli
; fli
= fli
->next
)
2918 if (! fli
->started_p
)
2922 oprintf (f
, "const struct ggc_root_tab gt_pch_rc_");
2923 put_mangled_filename (f
, v
->line
.file
);
2924 oprintf (f
, "[] = {\n");
2927 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2930 finish_root_table (flp
, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2931 "gt_pch_cache_rtab");
2933 for (v
= variables
; v
; v
= v
->next
)
2935 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2940 for (o
= v
->opt
; o
; o
= o
->next
)
2941 if (strcmp (o
->name
, "deletable") == 0
2942 || strcmp (o
->name
, "if_marked") == 0)
2948 if (! contains_scalar_p (v
->type
))
2951 for (fli
= flp
; fli
; fli
= fli
->next
)
2954 if (! fli
->started_p
)
2958 oprintf (f
, "const struct ggc_root_tab gt_pch_rs_");
2959 put_mangled_filename (f
, v
->line
.file
);
2960 oprintf (f
, "[] = {\n");
2963 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2967 finish_root_table (flp
, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2968 "gt_pch_scalar_rtab");
2972 extern int main (int argc
, char **argv
);
2974 main(int argc ATTRIBUTE_UNUSED
, char **argv ATTRIBUTE_UNUSED
)
2977 static struct fileloc pos
= { __FILE__
, __LINE__
};
2982 srcdir_len
= strlen (srcdir
);
2984 do_scalar_typedef ("CUMULATIVE_ARGS", &pos
);
2985 do_scalar_typedef ("REAL_VALUE_TYPE", &pos
);
2986 do_scalar_typedef ("uint8", &pos
);
2987 do_scalar_typedef ("jword", &pos
);
2988 do_scalar_typedef ("JCF_u2", &pos
);
2989 #ifdef USE_MAPPED_LOCATION
2990 do_scalar_typedef ("location_t", &pos
);
2991 do_scalar_typedef ("source_locus", &pos
);
2993 do_scalar_typedef ("void", &pos
);
2995 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos
)), &pos
);
2997 do_typedef ("HARD_REG_SET", create_array (
2998 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3001 for (i
= 0; i
< NUM_GT_FILES
; i
++)
3004 /* Omit if already seen. */
3005 for (j
= 0; j
< i
; j
++)
3007 if (!strcmp (all_files
[i
], all_files
[j
]))
3014 parse_file (all_files
[i
]);
3015 #ifndef USE_MAPPED_LOCATION
3016 /* temporary kludge - gengtype doesn't handle conditionals.
3017 Manually add source_locus *after* we've processed input.h. */
3019 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos
)), &pos
);
3026 set_gc_used (variables
);
3029 write_enum_defn (structures
, param_structs
);
3030 write_types (structures
, param_structs
, &ggc_wtd
);
3031 write_types (structures
, param_structs
, &pch_wtd
);
3032 write_local (structures
, param_structs
);
3033 write_roots (variables
);
3035 close_output_files ();
3037 return (hit_error
!= 0);