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 { "SAVE_EXPR", 2, 1 },
654 { "GOTO_SUBROUTINE_EXPR", 0, 2 },
655 { "RTL_EXPR", 0, 2 },
656 { "WITH_CLEANUP_EXPR", 2, 1 },
659 if (t
->kind
!= TYPE_ARRAY
)
661 error_at_line (&lexer_line
,
662 "special `tree_exp' must be applied to an array");
666 nodot
= xmalloc (sizeof (*nodot
));
671 flds
= xmalloc (sizeof (*flds
));
675 flds
->line
.file
= __FILE__
;
676 flds
->line
.line
= __LINE__
;
677 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
678 flds
->opt
->next
= nodot
;
679 flds
->opt
->name
= "length";
680 flds
->opt
->info
= "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
682 options_p oldopt
= flds
->opt
;
683 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
684 flds
->opt
->next
= oldopt
;
685 flds
->opt
->name
= "default";
686 flds
->opt
->info
= "";
689 for (i
= 0; i
< ARRAY_SIZE (data
); i
++)
691 pair_p old_flds
= flds
;
692 pair_p subfields
= NULL
;
697 r_index
< data
[i
].first_rtl
+ data
[i
].num_rtl
;
700 pair_p old_subf
= subfields
;
701 subfields
= xmalloc (sizeof (*subfields
));
702 subfields
->next
= old_subf
;
703 subfields
->name
= xasprintf ("[%d]", r_index
);
704 if (r_index
< data
[i
].first_rtl
)
705 subfields
->type
= t
->u
.a
.p
;
707 subfields
->type
= create_pointer (find_structure ("rtx_def", 0));
708 subfields
->line
.file
= __FILE__
;
709 subfields
->line
.line
= __LINE__
;
710 subfields
->opt
= nodot
;
713 flds
= xmalloc (sizeof (*flds
));
714 flds
->next
= old_flds
;
716 sname
= xasprintf ("tree_exp_%s", data
[i
].name
);
717 new_structure (sname
, 0, &lexer_line
, subfields
, NULL
);
718 flds
->type
= find_structure (sname
, 0);
719 flds
->line
.file
= __FILE__
;
720 flds
->line
.line
= __LINE__
;
721 flds
->opt
= xmalloc (sizeof (*flds
->opt
));
722 flds
->opt
->next
= nodot
;
723 flds
->opt
->name
= "tag";
724 flds
->opt
->info
= data
[i
].name
;
727 new_structure ("tree_exp_subunion", 1, &lexer_line
, flds
, nodot
);
728 return find_structure ("tree_exp_subunion", 1);
731 /* Perform any special processing on a type T, about to become the type
732 of a field. Return the appropriate type for the field.
734 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
735 - Similarly for arrays of pointer-to-char;
736 - Converts structures for which a parameter is provided to
738 - Handles "special" options.
742 adjust_field_type (type_p t
, options_p opt
)
745 const int pointer_p
= t
->kind
== TYPE_POINTER
;
746 type_p params
[NUM_PARAM
];
750 for (i
= 0; i
< NUM_PARAM
; i
++)
753 for (; opt
; opt
= opt
->next
)
754 if (strcmp (opt
->name
, "length") == 0)
756 else if (strcmp (opt
->name
, "param_is") == 0
757 || (strncmp (opt
->name
, "param", 5) == 0
758 && ISDIGIT (opt
->name
[5])
759 && strcmp (opt
->name
+ 6, "_is") == 0))
761 int num
= ISDIGIT (opt
->name
[5]) ? opt
->name
[5] - '0' : 0;
763 if (! UNION_OR_STRUCT_P (t
)
764 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
766 error_at_line (&lexer_line
,
767 "option `%s' may only be applied to structures or structure pointers",
773 if (params
[num
] != NULL
)
774 error_at_line (&lexer_line
, "duplicate `%s' option", opt
->name
);
775 if (! ISDIGIT (opt
->name
[5]))
776 params
[num
] = create_pointer ((type_p
) opt
->info
);
778 params
[num
] = (type_p
) opt
->info
;
780 else if (strcmp (opt
->name
, "special") == 0)
782 const char *special_name
= (const char *)opt
->info
;
783 if (strcmp (special_name
, "tree_exp") == 0)
784 t
= adjust_field_tree_exp (t
, opt
);
785 else if (strcmp (special_name
, "rtx_def") == 0)
786 t
= adjust_field_rtx_def (t
, opt
);
788 error_at_line (&lexer_line
, "unknown special `%s'", special_name
);
797 realt
= find_param_structure (t
, params
);
798 t
= pointer_p
? create_pointer (realt
) : realt
;
803 && t
->u
.p
->kind
== TYPE_SCALAR
804 && (strcmp (t
->u
.p
->u
.sc
, "char") == 0
805 || strcmp (t
->u
.p
->u
.sc
, "unsigned char") == 0))
807 if (t
->kind
== TYPE_ARRAY
&& t
->u
.a
.p
->kind
== TYPE_POINTER
808 && t
->u
.a
.p
->u
.p
->kind
== TYPE_SCALAR
809 && (strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "char") == 0
810 || strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "unsigned char") == 0))
811 return create_array (&string_type
, t
->u
.a
.len
);
816 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
817 and information about the correspondence between token types and fields
818 in TYPEINFO. POS is used for error messages. */
821 note_yacc_type (options_p o
, pair_p fields
, pair_p typeinfo
,
827 for (p
= typeinfo
; p
; p
= p
->next
)
834 if (p
->type
== (type_p
) 1)
839 for (pp
= typeinfo
; pp
; pp
= pp
->next
)
840 if (pp
->type
!= (type_p
) 1
841 && strcmp (pp
->opt
->info
, p
->opt
->info
) == 0)
850 for (m
= fields
; m
; m
= m
->next
)
851 if (strcmp (m
->name
, p
->name
) == 0)
855 error_at_line (&p
->line
,
856 "couldn't match fieldname `%s'", p
->name
);
867 || p
->type
== (type_p
) 1)
873 new_structure ("yy_union", 1, pos
, typeinfo
, o
);
874 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos
);
877 static void process_gc_options (options_p
, enum gc_used_enum
,
878 int *, int *, int *, type_p
*);
879 static void set_gc_used_type (type_p
, enum gc_used_enum
, type_p
*);
880 static void set_gc_used (pair_p
);
882 /* Handle OPT for set_gc_used_type. */
885 process_gc_options (options_p opt
, enum gc_used_enum level
, int *maybe_undef
,
886 int *pass_param
, int *length
, type_p
*nested_ptr
)
889 for (o
= opt
; o
; o
= o
->next
)
890 if (strcmp (o
->name
, "ptr_alias") == 0 && level
== GC_POINTED_TO
)
891 set_gc_used_type ((type_p
) o
->info
, GC_POINTED_TO
, NULL
);
892 else if (strcmp (o
->name
, "maybe_undef") == 0)
894 else if (strcmp (o
->name
, "use_params") == 0)
896 else if (strcmp (o
->name
, "length") == 0)
898 else if (strcmp (o
->name
, "nested_ptr") == 0)
899 *nested_ptr
= ((const struct nested_ptr_data
*) o
->info
)->type
;
902 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
905 set_gc_used_type (type_p t
, enum gc_used_enum level
, type_p param
[NUM_PARAM
])
907 if (t
->gc_used
>= level
)
921 process_gc_options (t
->u
.s
.opt
, level
, &dummy
, &dummy
, &dummy
,
924 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
929 type_p nested_ptr
= NULL
;
930 process_gc_options (f
->opt
, level
, &maybe_undef
, &pass_param
,
931 &length
, &nested_ptr
);
933 if (nested_ptr
&& f
->type
->kind
== TYPE_POINTER
)
934 set_gc_used_type (nested_ptr
, GC_POINTED_TO
,
935 pass_param
? param
: NULL
);
936 else if (length
&& f
->type
->kind
== TYPE_POINTER
)
937 set_gc_used_type (f
->type
->u
.p
, GC_USED
, NULL
);
938 else if (maybe_undef
&& f
->type
->kind
== TYPE_POINTER
)
939 set_gc_used_type (f
->type
->u
.p
, GC_MAYBE_POINTED_TO
, NULL
);
940 else if (pass_param
&& f
->type
->kind
== TYPE_POINTER
&& param
)
941 set_gc_used_type (find_param_structure (f
->type
->u
.p
, param
),
942 GC_POINTED_TO
, NULL
);
944 set_gc_used_type (f
->type
, GC_USED
, pass_param
? param
: NULL
);
950 set_gc_used_type (t
->u
.p
, GC_POINTED_TO
, NULL
);
954 set_gc_used_type (t
->u
.a
.p
, GC_USED
, param
);
957 case TYPE_LANG_STRUCT
:
958 for (t
= t
->u
.s
.lang_struct
; t
; t
= t
->next
)
959 set_gc_used_type (t
, level
, param
);
962 case TYPE_PARAM_STRUCT
:
965 for (i
= 0; i
< NUM_PARAM
; i
++)
966 if (t
->u
.param_struct
.param
[i
] != 0)
967 set_gc_used_type (t
->u
.param_struct
.param
[i
], GC_USED
, NULL
);
969 if (t
->u
.param_struct
.stru
->gc_used
== GC_POINTED_TO
)
970 level
= GC_POINTED_TO
;
973 t
->u
.param_struct
.stru
->gc_used
= GC_UNUSED
;
974 set_gc_used_type (t
->u
.param_struct
.stru
, level
,
975 t
->u
.param_struct
.param
);
983 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
986 set_gc_used (pair_p variables
)
989 for (p
= variables
; p
; p
= p
->next
)
990 set_gc_used_type (p
->type
, GC_USED
, NULL
);
993 /* File mapping routines. For each input file, there is one output .c file
994 (but some output files have many input files), and there is one .h file
995 for the whole build. */
997 /* The list of output files. */
998 static outf_p output_files
;
1000 /* The output header file that is included into pretty much every
1002 static outf_p header_file
;
1004 /* Number of files specified in gtfiles. */
1005 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1007 /* Number of files in the language files array. */
1008 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1010 /* Length of srcdir name. */
1011 static int srcdir_len
= 0;
1013 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1014 outf_p base_files
[NUM_BASE_FILES
];
1016 static outf_p
create_file (const char *, const char *);
1017 static const char * get_file_basename (const char *);
1019 /* Create and return an outf_p for a new file for NAME, to be called
1023 create_file (const char *name
, const char *oname
)
1025 static const char *const hdr
[] = {
1026 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
1028 "This file is part of GCC.\n",
1030 "GCC is free software; you can redistribute it and/or modify it under\n",
1031 "the terms of the GNU General Public License as published by the Free\n",
1032 "Software Foundation; either version 2, or (at your option) any later\n",
1035 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1036 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1037 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1038 "for more details.\n",
1040 "You should have received a copy of the GNU General Public License\n",
1041 "along with GCC; see the file COPYING. If not, write to the Free\n",
1042 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
1043 "02111-1307, USA. */\n",
1045 "/* This file is machine generated. Do not edit. */\n"
1050 f
= xcalloc (sizeof (*f
), 1);
1051 f
->next
= output_files
;
1055 oprintf (f
, "/* Type information for %s.\n", name
);
1056 for (i
= 0; i
< ARRAY_SIZE (hdr
); i
++)
1057 oprintf (f
, "%s", hdr
[i
]);
1061 /* Print, like fprintf, to O. */
1063 oprintf (outf_p o
, const char *format
, ...)
1069 va_start (ap
, format
);
1070 slength
= xvasprintf (&s
, format
, ap
);
1072 if (o
->bufused
+ slength
> o
->buflength
)
1074 size_t new_len
= o
->buflength
;
1079 } while (o
->bufused
+ slength
>= new_len
);
1080 o
->buf
= xrealloc (o
->buf
, new_len
);
1081 o
->buflength
= new_len
;
1083 memcpy (o
->buf
+ o
->bufused
, s
, slength
);
1084 o
->bufused
+= slength
;
1089 /* Open the global header file and the language-specific header files. */
1092 open_base_files (void)
1096 header_file
= create_file ("GCC", "gtype-desc.h");
1098 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1099 base_files
[i
] = create_file (lang_dir_names
[i
],
1100 xasprintf ("gtype-%s.h", lang_dir_names
[i
]));
1102 /* gtype-desc.c is a little special, so we create it here. */
1104 /* The order of files here matters very much. */
1105 static const char *const ifiles
[] = {
1106 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1107 "hashtab.h", "splay-tree.h", "bitmap.h", "input.h", "tree.h", "rtl.h",
1108 "function.h", "insn-config.h", "expr.h", "hard-reg-set.h",
1109 "basic-block.h", "cselib.h", "insn-addr.h", "optabs.h",
1110 "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1111 "tree-alias-type.h", "tree-flow.h", "reload.h",
1116 const char *const *ifp
;
1117 outf_p gtype_desc_c
;
1119 gtype_desc_c
= create_file ("GCC", "gtype-desc.c");
1120 for (ifp
= ifiles
; *ifp
; ifp
++)
1121 oprintf (gtype_desc_c
, "#include \"%s\"\n", *ifp
);
1125 /* Determine the pathname to F relative to $(srcdir). */
1128 get_file_basename (const char *f
)
1130 const char *basename
;
1133 basename
= strrchr (f
, '/');
1140 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1146 s1
= basename
- strlen (lang_dir_names
[i
]) - 1;
1147 s2
= lang_dir_names
[i
];
1150 if (l1
>= l2
&& !memcmp (s1
, s2
, l2
))
1153 if ((basename
- f
- 1) != srcdir_len
)
1154 abort (); /* Match is wrong - should be preceded by $srcdir. */
1162 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1163 INPUT_FILE is used by <lang>.
1165 This function should be written to assume that a file _is_ used
1166 if the situation is unclear. If it wrongly assumes a file _is_ used,
1167 a linker error will result. If it wrongly assumes a file _is not_ used,
1168 some GC roots may be missed, which is a much harder-to-debug problem. */
1171 get_base_file_bitmap (const char *input_file
)
1173 const char *basename
= get_file_basename (input_file
);
1174 const char *slashpos
= strchr (basename
, '/');
1182 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1183 if ((size_t)(slashpos
- basename
) == strlen (lang_dir_names
[i
])
1184 && memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0)
1186 /* It's in a language directory, set that language. */
1191 abort (); /* Should have found the language. */
1194 /* If it's in any config-lang.in, then set for the languages
1199 for (j
= 0; j
< NUM_LANG_FILES
; j
++)
1201 if (!strcmp(input_file
, lang_files
[j
]))
1203 for (k
= 0; k
< NUM_BASE_FILES
; k
++)
1205 if (!strcmp(lang_dir_names
[k
], langs_for_lang_files
[j
]))
1211 /* Otherwise, set all languages. */
1213 bitmap
= (1 << NUM_BASE_FILES
) - 1;
1218 /* An output file, suitable for definitions, that can see declarations
1219 made in INPUT_FILE and is linked into every language that uses
1223 get_output_file_with_visibility (const char *input_file
)
1227 const char *basename
;
1228 const char *for_name
;
1229 const char *output_name
;
1231 /* This can happen when we need a file with visibility on a
1232 structure that we've never seen. We have to just hope that it's
1233 globally visible. */
1234 if (input_file
== NULL
)
1235 input_file
= "system.h";
1237 /* Determine the output file name. */
1238 basename
= get_file_basename (input_file
);
1240 len
= strlen (basename
);
1241 if ((len
> 2 && memcmp (basename
+len
-2, ".c", 2) == 0)
1242 || (len
> 2 && memcmp (basename
+len
-2, ".y", 2) == 0)
1243 || (len
> 3 && memcmp (basename
+len
-3, ".in", 3) == 0))
1247 output_name
= s
= xasprintf ("gt-%s", basename
);
1248 for (; *s
!= '.'; s
++)
1249 if (! ISALNUM (*s
) && *s
!= '-')
1251 memcpy (s
, ".h", sizeof (".h"));
1252 for_name
= basename
;
1254 else if (strcmp (basename
, "c-common.h") == 0)
1255 output_name
= "gt-c-common.h", for_name
= "c-common.c";
1256 else if (strcmp (basename
, "c-tree.h") == 0)
1257 output_name
= "gt-c-decl.h", for_name
= "c-decl.c";
1262 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1263 if (memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0
1264 && basename
[strlen(lang_dir_names
[i
])] == '/')
1265 return base_files
[i
];
1267 output_name
= "gtype-desc.c";
1271 /* Look through to see if we've ever seen this output filename before. */
1272 for (r
= output_files
; r
; r
= r
->next
)
1273 if (strcmp (r
->name
, output_name
) == 0)
1276 /* If not, create it. */
1277 r
= create_file (for_name
, output_name
);
1282 /* The name of an output file, suitable for definitions, that can see
1283 declarations made in INPUT_FILE and is linked into every language
1284 that uses INPUT_FILE. */
1287 get_output_file_name (const char *input_file
)
1289 return get_output_file_with_visibility (input_file
)->name
;
1292 /* Copy the output to its final destination,
1293 but don't unnecessarily change modification times. */
1296 close_output_files (void)
1300 for (of
= output_files
; of
; of
= of
->next
)
1304 newfile
= fopen (of
->name
, "r");
1305 if (newfile
!= NULL
)
1310 for (i
= 0; i
< of
->bufused
; i
++)
1313 ch
= fgetc (newfile
);
1314 if (ch
== EOF
|| ch
!= (unsigned char) of
->buf
[i
])
1317 no_write_p
= i
== of
->bufused
&& fgetc (newfile
) == EOF
;
1324 newfile
= fopen (of
->name
, "w");
1325 if (newfile
== NULL
)
1327 perror ("opening output file");
1330 if (fwrite (of
->buf
, 1, of
->bufused
, newfile
) != of
->bufused
)
1332 perror ("writing output file");
1335 if (fclose (newfile
) != 0)
1337 perror ("closing output file");
1350 struct walk_type_data
;
1352 /* For scalars and strings, given the item in 'val'.
1353 For structures, given a pointer to the item in 'val'.
1354 For misc. pointers, given the item in 'val'.
1356 typedef void (*process_field_fn
)
1357 (type_p f
, const struct walk_type_data
*p
);
1358 typedef void (*func_name_fn
)
1359 (type_p s
, const struct walk_type_data
*p
);
1361 /* Parameters for write_types. */
1363 struct write_types_data
1366 const char *param_prefix
;
1367 const char *subfield_marker_routine
;
1368 const char *marker_routine
;
1369 const char *reorder_note_routine
;
1370 const char *comment
;
1373 static void output_escaped_param (struct walk_type_data
*d
,
1374 const char *, const char *);
1375 static void output_mangled_typename (outf_p
, type_p
);
1376 static void walk_type (type_p t
, struct walk_type_data
*d
);
1377 static void write_func_for_structure
1378 (type_p orig_s
, type_p s
, type_p
* param
,
1379 const struct write_types_data
*wtd
);
1380 static void write_types_process_field
1381 (type_p f
, const struct walk_type_data
*d
);
1382 static void write_types (type_p structures
,
1383 type_p param_structs
,
1384 const struct write_types_data
*wtd
);
1385 static void write_types_local_process_field
1386 (type_p f
, const struct walk_type_data
*d
);
1387 static void write_local_func_for_structure
1388 (type_p orig_s
, type_p s
, type_p
* param
);
1389 static void write_local (type_p structures
,
1390 type_p param_structs
);
1391 static void write_enum_defn (type_p structures
, type_p param_structs
);
1392 static int contains_scalar_p (type_p t
);
1393 static void put_mangled_filename (outf_p
, const char *);
1394 static void finish_root_table (struct flist
*flp
, const char *pfx
,
1395 const char *tname
, const char *lastname
,
1397 static void write_root (outf_p
, pair_p
, type_p
, const char *, int,
1398 struct fileloc
*, const char *);
1399 static void write_array (outf_p f
, pair_p v
,
1400 const struct write_types_data
*wtd
);
1401 static void write_roots (pair_p
);
1403 /* Parameters for walk_type. */
1405 struct walk_type_data
1407 process_field_fn process_field
;
1412 const char *prev_val
[4];
1415 struct fileloc
*line
;
1420 const char *reorder_fn
;
1422 bool fn_wants_lvalue
;
1425 /* Print a mangled name representing T to OF. */
1428 output_mangled_typename (outf_p of
, type_p t
)
1432 else switch (t
->kind
)
1436 output_mangled_typename (of
, t
->u
.p
);
1446 case TYPE_LANG_STRUCT
:
1447 oprintf (of
, "%lu%s", (unsigned long) strlen (t
->u
.s
.tag
), t
->u
.s
.tag
);
1449 case TYPE_PARAM_STRUCT
:
1452 for (i
= 0; i
< NUM_PARAM
; i
++)
1453 if (t
->u
.param_struct
.param
[i
] != NULL
)
1454 output_mangled_typename (of
, t
->u
.param_struct
.param
[i
]);
1455 output_mangled_typename (of
, t
->u
.param_struct
.stru
);
1463 /* Print PARAM to D->OF processing escapes. D->VAL references the
1464 current object, D->PREV_VAL the object containing the current
1465 object, ONAME is the name of the option and D->LINE is used to
1466 print error messages. */
1469 output_escaped_param (struct walk_type_data
*d
, const char *param
,
1474 for (p
= param
; *p
; p
++)
1476 oprintf (d
->of
, "%c", *p
);
1480 oprintf (d
->of
, "(%s)", d
->prev_val
[2]);
1483 oprintf (d
->of
, "(%s)", d
->prev_val
[0]);
1486 oprintf (d
->of
, "(%s)", d
->prev_val
[1]);
1490 const char *pp
= d
->val
+ strlen (d
->val
);
1491 while (pp
[-1] == ']')
1494 oprintf (d
->of
, "%s", pp
);
1498 error_at_line (d
->line
, "`%s' option contains bad escape %c%c",
1503 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1504 which is of type T. Write code to D->OF to constrain execution (at
1505 the point that D->PROCESS_FIELD is called) to the appropriate
1506 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1507 pointers to those objects. D->PREV_VAL lists the objects
1508 containing the current object, D->OPT is a list of options to
1509 apply, D->INDENT is the current indentation level, D->LINE is used
1510 to print error messages, D->BITMAP indicates which languages to
1511 print the structure for, and D->PARAM is the current parameter
1512 (from an enclosing param_is option). */
1515 walk_type (type_p t
, struct walk_type_data
*d
)
1517 const char *length
= NULL
;
1518 const char *desc
= NULL
;
1519 int maybe_undef_p
= 0;
1520 int use_param_num
= -1;
1521 int use_params_p
= 0;
1523 const struct nested_ptr_data
*nested_ptr_d
= NULL
;
1525 d
->needs_cast_p
= false;
1526 for (oo
= d
->opt
; oo
; oo
= oo
->next
)
1527 if (strcmp (oo
->name
, "length") == 0)
1528 length
= (const char *)oo
->info
;
1529 else if (strcmp (oo
->name
, "maybe_undef") == 0)
1531 else if (strncmp (oo
->name
, "use_param", 9) == 0
1532 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1533 use_param_num
= oo
->name
[9] == '\0' ? 0 : oo
->name
[9] - '0';
1534 else if (strcmp (oo
->name
, "use_params") == 0)
1536 else if (strcmp (oo
->name
, "desc") == 0)
1537 desc
= (const char *)oo
->info
;
1538 else if (strcmp (oo
->name
, "nested_ptr") == 0)
1539 nested_ptr_d
= (const struct nested_ptr_data
*) oo
->info
;
1540 else if (strcmp (oo
->name
, "dot") == 0)
1542 else if (strcmp (oo
->name
, "tag") == 0)
1544 else if (strcmp (oo
->name
, "special") == 0)
1546 else if (strcmp (oo
->name
, "skip") == 0)
1548 else if (strcmp (oo
->name
, "default") == 0)
1550 else if (strcmp (oo
->name
, "descbits") == 0)
1552 else if (strcmp (oo
->name
, "param_is") == 0)
1554 else if (strncmp (oo
->name
, "param", 5) == 0
1555 && ISDIGIT (oo
->name
[5])
1556 && strcmp (oo
->name
+ 6, "_is") == 0)
1558 else if (strcmp (oo
->name
, "chain_next") == 0)
1560 else if (strcmp (oo
->name
, "chain_prev") == 0)
1562 else if (strcmp (oo
->name
, "reorder") == 0)
1565 error_at_line (d
->line
, "unknown option `%s'\n", oo
->name
);
1572 int pointer_p
= t
->kind
== TYPE_POINTER
;
1576 if (! UNION_OR_STRUCT_P (t
))
1577 error_at_line (d
->line
, "`use_params' option on unimplemented type");
1579 t
= find_param_structure (t
, d
->param
);
1581 t
= create_pointer (t
);
1584 if (use_param_num
!= -1)
1586 if (d
->param
!= NULL
&& d
->param
[use_param_num
] != NULL
)
1588 type_p nt
= d
->param
[use_param_num
];
1590 if (t
->kind
== TYPE_ARRAY
)
1591 nt
= create_array (nt
, t
->u
.a
.len
);
1592 else if (length
!= NULL
&& t
->kind
== TYPE_POINTER
)
1593 nt
= create_pointer (nt
);
1594 d
->needs_cast_p
= (t
->kind
!= TYPE_POINTER
1595 && (nt
->kind
== TYPE_POINTER
1596 || nt
->kind
== TYPE_STRING
));
1600 error_at_line (d
->line
, "no parameter defined for `%s'",
1605 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
1607 error_at_line (d
->line
,
1608 "field `%s' has invalid option `maybe_undef_p'\n",
1617 d
->process_field (t
, d
);
1623 && t
->u
.p
->u
.s
.line
.file
== NULL
)
1625 oprintf (d
->of
, "%*sif (%s) abort();\n", d
->indent
, "", d
->val
);
1631 if (! UNION_OR_STRUCT_P (t
->u
.p
)
1632 && t
->u
.p
->kind
!= TYPE_PARAM_STRUCT
)
1634 error_at_line (d
->line
,
1635 "field `%s' is pointer to unimplemented type",
1642 const char *oldprevval2
= d
->prev_val
[2];
1644 if (! UNION_OR_STRUCT_P (nested_ptr_d
->type
))
1646 error_at_line (d
->line
,
1647 "field `%s' has invalid "
1648 "option `nested_ptr'\n",
1653 d
->prev_val
[2] = d
->val
;
1654 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1656 d
->val
= xasprintf ("x%d", d
->counter
++);
1657 oprintf (d
->of
, "%*s%s %s * %s%s =\n", d
->indent
, "",
1658 (nested_ptr_d
->type
->kind
== TYPE_UNION
1659 ? "union" : "struct"),
1660 nested_ptr_d
->type
->u
.s
.tag
,
1661 d
->fn_wants_lvalue
? "" : "const ",
1663 oprintf (d
->of
, "%*s", d
->indent
+ 2, "");
1664 output_escaped_param (d
, nested_ptr_d
->convert_from
,
1666 oprintf (d
->of
, ";\n");
1668 d
->process_field (nested_ptr_d
->type
, d
);
1670 if (d
->fn_wants_lvalue
)
1672 oprintf (d
->of
, "%*s%s = ", d
->indent
, "",
1674 d
->prev_val
[2] = d
->val
;
1675 output_escaped_param (d
, nested_ptr_d
->convert_to
,
1677 oprintf (d
->of
, ";\n");
1681 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1682 d
->val
= d
->prev_val
[2];
1683 d
->prev_val
[2] = oldprevval2
;
1686 d
->process_field (t
->u
.p
, d
);
1690 int loopcounter
= d
->counter
++;
1691 const char *oldval
= d
->val
;
1692 const char *oldprevval3
= d
->prev_val
[3];
1695 oprintf (d
->of
, "%*sif (%s != NULL) {\n", d
->indent
, "", d
->val
);
1697 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1698 oprintf (d
->of
, "%*sfor (i%d = 0; i%d < (size_t)(", d
->indent
, "",
1699 loopcounter
, loopcounter
);
1700 output_escaped_param (d
, length
, "length");
1701 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1703 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1705 d
->prev_val
[3] = oldval
;
1706 walk_type (t
->u
.p
, d
);
1709 d
->prev_val
[3] = oldprevval3
;
1712 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1713 d
->process_field(t
, d
);
1715 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1722 int loopcounter
= d
->counter
++;
1723 const char *oldval
= d
->val
;
1726 /* If it's an array of scalars, we optimize by not generating
1728 if (t
->u
.a
.p
->kind
== TYPE_SCALAR
)
1731 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1733 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1734 oprintf (d
->of
, "%*sfor (i%d = 0; i%d < (size_t)(", d
->indent
, "",
1735 loopcounter
, loopcounter
);
1737 output_escaped_param (d
, length
, "length");
1739 oprintf (d
->of
, "%s", t
->u
.a
.len
);
1740 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1742 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1744 walk_type (t
->u
.a
.p
, d
);
1749 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1751 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1759 const char *oldval
= d
->val
;
1760 const char *oldprevval1
= d
->prev_val
[1];
1761 const char *oldprevval2
= d
->prev_val
[2];
1762 const int union_p
= t
->kind
== TYPE_UNION
;
1763 int seen_default_p
= 0;
1766 if (! t
->u
.s
.line
.file
)
1767 error_at_line (d
->line
, "incomplete structure `%s'", t
->u
.s
.tag
);
1769 if ((d
->bitmap
& t
->u
.s
.bitmap
) != d
->bitmap
)
1771 error_at_line (d
->line
,
1772 "structure `%s' defined for mismatching languages",
1774 error_at_line (&t
->u
.s
.line
, "one structure defined here");
1777 /* Some things may also be defined in the structure's options. */
1778 for (o
= t
->u
.s
.opt
; o
; o
= o
->next
)
1779 if (! desc
&& strcmp (o
->name
, "desc") == 0)
1780 desc
= (const char *)o
->info
;
1782 d
->prev_val
[2] = oldval
;
1783 d
->prev_val
[1] = oldprevval2
;
1788 error_at_line (d
->line
, "missing `desc' option for union `%s'",
1792 oprintf (d
->of
, "%*sswitch (", d
->indent
, "");
1793 output_escaped_param (d
, desc
, "desc");
1794 oprintf (d
->of
, ")\n");
1796 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1798 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
1801 const char *dot
= ".";
1802 const char *tagid
= NULL
;
1805 int use_param_p
= 0;
1808 d
->reorder_fn
= NULL
;
1809 for (oo
= f
->opt
; oo
; oo
= oo
->next
)
1810 if (strcmp (oo
->name
, "dot") == 0)
1811 dot
= (const char *)oo
->info
;
1812 else if (strcmp (oo
->name
, "tag") == 0)
1813 tagid
= (const char *)oo
->info
;
1814 else if (strcmp (oo
->name
, "skip") == 0)
1816 else if (strcmp (oo
->name
, "default") == 0)
1818 else if (strcmp (oo
->name
, "reorder") == 0)
1819 d
->reorder_fn
= (const char *)oo
->info
;
1820 else if (strncmp (oo
->name
, "use_param", 9) == 0
1821 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1827 if (union_p
&& tagid
)
1829 oprintf (d
->of
, "%*scase %s:\n", d
->indent
, "", tagid
);
1832 else if (union_p
&& default_p
)
1834 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1838 else if (! union_p
&& (default_p
|| tagid
))
1839 error_at_line (d
->line
,
1840 "can't use `%s' outside a union on field `%s'",
1841 default_p
? "default" : "tag", f
->name
);
1842 else if (union_p
&& ! (default_p
|| tagid
)
1843 && f
->type
->kind
== TYPE_SCALAR
)
1846 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1847 d
->line
->file
, d
->line
->line
, f
->name
);
1850 else if (union_p
&& ! (default_p
|| tagid
))
1851 error_at_line (d
->line
,
1852 "field `%s' is missing `tag' or `default' option",
1856 d
->val
= newval
= xasprintf ("%s%s%s", oldval
, dot
, f
->name
);
1858 d
->used_length
= false;
1860 if (union_p
&& use_param_p
&& d
->param
== NULL
)
1861 oprintf (d
->of
, "%*sabort();\n", d
->indent
, "");
1863 walk_type (f
->type
, d
);
1869 oprintf (d
->of
, "%*sbreak;\n", d
->indent
, "");
1873 d
->reorder_fn
= NULL
;
1876 d
->prev_val
[1] = oldprevval1
;
1877 d
->prev_val
[2] = oldprevval2
;
1879 if (union_p
&& ! seen_default_p
)
1881 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1882 oprintf (d
->of
, "%*s break;\n", d
->indent
, "");
1886 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1892 case TYPE_LANG_STRUCT
:
1895 for (nt
= t
->u
.s
.lang_struct
; nt
; nt
= nt
->next
)
1896 if ((d
->bitmap
& nt
->u
.s
.bitmap
) == d
->bitmap
)
1899 error_at_line (d
->line
, "structure `%s' differs between languages",
1906 case TYPE_PARAM_STRUCT
:
1908 type_p
*oldparam
= d
->param
;
1910 d
->param
= t
->u
.param_struct
.param
;
1911 walk_type (t
->u
.param_struct
.stru
, d
);
1912 d
->param
= oldparam
;
1921 /* process_field routine for marking routines. */
1924 write_types_process_field (type_p f
, const struct walk_type_data
*d
)
1926 const struct write_types_data
*wtd
;
1927 const char *cast
= d
->needs_cast_p
? "(void *)" : "";
1928 wtd
= (const struct write_types_data
*) d
->cookie
;
1933 oprintf (d
->of
, "%*s%s (%s%s", d
->indent
, "",
1934 wtd
->subfield_marker_routine
, cast
, d
->val
);
1935 if (wtd
->param_prefix
)
1937 oprintf (d
->of
, ", %s", d
->prev_val
[3]);
1940 oprintf (d
->of
, ", gt_%s_", wtd
->param_prefix
);
1941 output_mangled_typename (d
->of
, d
->orig_s
);
1944 oprintf (d
->of
, ", gt_%sa_%s", wtd
->param_prefix
, d
->prev_val
[0]);
1946 oprintf (d
->of
, ");\n");
1947 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1948 oprintf (d
->of
, "%*s%s (%s%s, %s, %s);\n", d
->indent
, "",
1949 wtd
->reorder_note_routine
, cast
, d
->val
,
1950 d
->prev_val
[3], d
->reorder_fn
);
1954 if (wtd
->param_prefix
== NULL
)
1959 case TYPE_LANG_STRUCT
:
1960 case TYPE_PARAM_STRUCT
:
1961 oprintf (d
->of
, "%*sgt_%s_", d
->indent
, "", wtd
->prefix
);
1962 output_mangled_typename (d
->of
, f
);
1963 oprintf (d
->of
, " (%s%s);\n", cast
, d
->val
);
1964 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1965 oprintf (d
->of
, "%*s%s (%s%s, %s%s, %s);\n", d
->indent
, "",
1966 wtd
->reorder_note_routine
, cast
, d
->val
, cast
, d
->val
,
1978 /* For S, a structure that's part of ORIG_S, and using parameters
1979 PARAM, write out a routine that:
1980 - Takes a parameter, a void * but actually of type *S
1981 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1982 field of S or its substructures and (in some cases) things
1983 that are pointed to by S.
1987 write_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
,
1988 const struct write_types_data
*wtd
)
1990 const char *fn
= s
->u
.s
.line
.file
;
1992 const char *chain_next
= NULL
;
1993 const char *chain_prev
= NULL
;
1995 struct walk_type_data d
;
1997 /* This is a hack, and not the good kind either. */
1998 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
1999 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
2000 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
2001 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2003 memset (&d
, 0, sizeof (d
));
2004 d
.of
= get_output_file_with_visibility (fn
);
2006 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2007 if (strcmp (opt
->name
, "chain_next") == 0)
2008 chain_next
= (const char *) opt
->info
;
2009 else if (strcmp (opt
->name
, "chain_prev") == 0)
2010 chain_prev
= (const char *) opt
->info
;
2012 if (chain_prev
!= NULL
&& chain_next
== NULL
)
2013 error_at_line (&s
->u
.s
.line
, "chain_prev without chain_next");
2015 d
.process_field
= write_types_process_field
;
2019 d
.line
= &s
->u
.s
.line
;
2020 d
.bitmap
= s
->u
.s
.bitmap
;
2022 d
.prev_val
[0] = "*x";
2023 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2024 d
.prev_val
[3] = "x";
2027 oprintf (d
.of
, "\n");
2028 oprintf (d
.of
, "void\n");
2030 oprintf (d
.of
, "gt_%sx_%s", wtd
->prefix
, orig_s
->u
.s
.tag
);
2033 oprintf (d
.of
, "gt_%s_", wtd
->prefix
);
2034 output_mangled_typename (d
.of
, orig_s
);
2036 oprintf (d
.of
, " (void *x_p)\n");
2037 oprintf (d
.of
, "{\n");
2038 oprintf (d
.of
, " %s %s * %sx = (%s %s *)x_p;\n",
2039 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2040 chain_next
== NULL
? "const " : "",
2041 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2042 if (chain_next
!= NULL
)
2043 oprintf (d
.of
, " %s %s * xlimit = x;\n",
2044 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2045 if (chain_next
== NULL
)
2047 oprintf (d
.of
, " if (%s (x", wtd
->marker_routine
);
2048 if (wtd
->param_prefix
)
2050 oprintf (d
.of
, ", x, gt_%s_", wtd
->param_prefix
);
2051 output_mangled_typename (d
.of
, orig_s
);
2053 oprintf (d
.of
, "))\n");
2057 oprintf (d
.of
, " while (%s (xlimit", wtd
->marker_routine
);
2058 if (wtd
->param_prefix
)
2060 oprintf (d
.of
, ", xlimit, gt_%s_", wtd
->param_prefix
);
2061 output_mangled_typename (d
.of
, orig_s
);
2063 oprintf (d
.of
, "))\n");
2064 oprintf (d
.of
, " xlimit = (");
2065 d
.prev_val
[2] = "*xlimit";
2066 output_escaped_param (&d
, chain_next
, "chain_next");
2067 oprintf (d
.of
, ");\n");
2068 if (chain_prev
!= NULL
)
2070 oprintf (d
.of
, " if (x != xlimit)\n");
2071 oprintf (d
.of
, " for (;;)\n");
2072 oprintf (d
.of
, " {\n");
2073 oprintf (d
.of
, " %s %s * const xprev = (",
2074 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2076 d
.prev_val
[2] = "*x";
2077 output_escaped_param (&d
, chain_prev
, "chain_prev");
2078 oprintf (d
.of
, ");\n");
2079 oprintf (d
.of
, " if (xprev == NULL) break;\n");
2080 oprintf (d
.of
, " x = xprev;\n");
2081 oprintf (d
.of
, " (void) %s (xprev",
2082 wtd
->marker_routine
);
2083 if (wtd
->param_prefix
)
2085 oprintf (d
.of
, ", xprev, gt_%s_", wtd
->param_prefix
);
2086 output_mangled_typename (d
.of
, orig_s
);
2088 oprintf (d
.of
, ");\n");
2089 oprintf (d
.of
, " }\n");
2091 oprintf (d
.of
, " while (x != xlimit)\n");
2093 oprintf (d
.of
, " {\n");
2095 d
.prev_val
[2] = "*x";
2099 if (chain_next
!= NULL
)
2101 oprintf (d
.of
, " x = (");
2102 output_escaped_param (&d
, chain_next
, "chain_next");
2103 oprintf (d
.of
, ");\n");
2106 oprintf (d
.of
, " }\n");
2107 oprintf (d
.of
, "}\n");
2110 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2113 write_types (type_p structures
, type_p param_structs
,
2114 const struct write_types_data
*wtd
)
2118 oprintf (header_file
, "\n/* %s*/\n", wtd
->comment
);
2119 for (s
= structures
; s
; s
= s
->next
)
2120 if (s
->gc_used
== GC_POINTED_TO
2121 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2125 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2126 && s
->u
.s
.line
.file
== NULL
)
2129 oprintf (header_file
, "#define gt_%s_", wtd
->prefix
);
2130 output_mangled_typename (header_file
, s
);
2131 oprintf (header_file
, "(X) do { \\\n");
2132 oprintf (header_file
,
2133 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd
->prefix
,
2135 oprintf (header_file
,
2138 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2139 if (strcmp (opt
->name
, "ptr_alias") == 0)
2141 type_p t
= (type_p
) opt
->info
;
2142 if (t
->kind
== TYPE_STRUCT
2143 || t
->kind
== TYPE_UNION
2144 || t
->kind
== TYPE_LANG_STRUCT
)
2145 oprintf (header_file
,
2146 "#define gt_%sx_%s gt_%sx_%s\n",
2147 wtd
->prefix
, s
->u
.s
.tag
, wtd
->prefix
, t
->u
.s
.tag
);
2149 error_at_line (&s
->u
.s
.line
,
2150 "structure alias is not a structure");
2156 /* Declare the marker procedure only once. */
2157 oprintf (header_file
,
2158 "extern void gt_%sx_%s (void *);\n",
2159 wtd
->prefix
, s
->u
.s
.tag
);
2161 if (s
->u
.s
.line
.file
== NULL
)
2163 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2168 if (s
->kind
== TYPE_LANG_STRUCT
)
2171 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2172 write_func_for_structure (s
, ss
, NULL
, wtd
);
2175 write_func_for_structure (s
, s
, NULL
, wtd
);
2178 for (s
= param_structs
; s
; s
= s
->next
)
2179 if (s
->gc_used
== GC_POINTED_TO
)
2181 type_p
* param
= s
->u
.param_struct
.param
;
2182 type_p stru
= s
->u
.param_struct
.stru
;
2184 /* Declare the marker procedure. */
2185 oprintf (header_file
, "extern void gt_%s_", wtd
->prefix
);
2186 output_mangled_typename (header_file
, s
);
2187 oprintf (header_file
, " (void *);\n");
2189 if (stru
->u
.s
.line
.file
== NULL
)
2191 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2196 if (stru
->kind
== TYPE_LANG_STRUCT
)
2199 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2200 write_func_for_structure (s
, ss
, param
, wtd
);
2203 write_func_for_structure (s
, stru
, param
, wtd
);
2207 static const struct write_types_data ggc_wtd
=
2209 "ggc_m", NULL
, "ggc_mark", "ggc_test_and_set_mark", NULL
,
2210 "GC marker procedures. "
2213 static const struct write_types_data pch_wtd
=
2215 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2216 "gt_pch_note_reorder",
2217 "PCH type-walking procedures. "
2220 /* Write out the local pointer-walking routines. */
2222 /* process_field routine for local pointer-walking. */
2225 write_types_local_process_field (type_p f
, const struct walk_type_data
*d
)
2232 case TYPE_LANG_STRUCT
:
2233 case TYPE_PARAM_STRUCT
:
2235 oprintf (d
->of
, "%*sif ((void *)(%s) == this_obj)\n", d
->indent
, "",
2237 oprintf (d
->of
, "%*s op (&(%s), cookie);\n", d
->indent
, "", d
->val
);
2248 /* For S, a structure that's part of ORIG_S, and using parameters
2249 PARAM, write out a routine that:
2250 - Is of type gt_note_pointers
2251 - Calls PROCESS_FIELD on each field of S or its substructures.
2255 write_local_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
)
2257 const char *fn
= s
->u
.s
.line
.file
;
2259 struct walk_type_data d
;
2261 /* This is a hack, and not the good kind either. */
2262 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
2263 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
2264 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
2265 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2267 memset (&d
, 0, sizeof (d
));
2268 d
.of
= get_output_file_with_visibility (fn
);
2270 d
.process_field
= write_types_local_process_field
;
2272 d
.line
= &s
->u
.s
.line
;
2273 d
.bitmap
= s
->u
.s
.bitmap
;
2275 d
.prev_val
[0] = d
.prev_val
[2] = "*x";
2276 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2277 d
.prev_val
[3] = "x";
2279 d
.fn_wants_lvalue
= true;
2281 oprintf (d
.of
, "\n");
2282 oprintf (d
.of
, "void\n");
2283 oprintf (d
.of
, "gt_pch_p_");
2284 output_mangled_typename (d
.of
, orig_s
);
2285 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");
2286 oprintf (d
.of
, "{\n");
2287 oprintf (d
.of
, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2288 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2289 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2292 oprintf (d
.of
, "}\n");
2295 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2298 write_local (type_p structures
, type_p param_structs
)
2302 oprintf (header_file
, "\n/* Local pointer-walking routines. */\n");
2303 for (s
= structures
; s
; s
= s
->next
)
2304 if (s
->gc_used
== GC_POINTED_TO
2305 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2309 if (s
->u
.s
.line
.file
== NULL
)
2312 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2313 if (strcmp (opt
->name
, "ptr_alias") == 0)
2315 type_p t
= (type_p
) opt
->info
;
2316 if (t
->kind
== TYPE_STRUCT
2317 || t
->kind
== TYPE_UNION
2318 || t
->kind
== TYPE_LANG_STRUCT
)
2320 oprintf (header_file
, "#define gt_pch_p_");
2321 output_mangled_typename (header_file
, s
);
2322 oprintf (header_file
, " gt_pch_p_");
2323 output_mangled_typename (header_file
, t
);
2324 oprintf (header_file
, "\n");
2327 error_at_line (&s
->u
.s
.line
,
2328 "structure alias is not a structure");
2334 /* Declare the marker procedure only once. */
2335 oprintf (header_file
, "extern void gt_pch_p_");
2336 output_mangled_typename (header_file
, s
);
2337 oprintf (header_file
,
2338 "\n (void *, void *, gt_pointer_operator, void *);\n");
2340 if (s
->kind
== TYPE_LANG_STRUCT
)
2343 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2344 write_local_func_for_structure (s
, ss
, NULL
);
2347 write_local_func_for_structure (s
, s
, NULL
);
2350 for (s
= param_structs
; s
; s
= s
->next
)
2351 if (s
->gc_used
== GC_POINTED_TO
)
2353 type_p
* param
= s
->u
.param_struct
.param
;
2354 type_p stru
= s
->u
.param_struct
.stru
;
2356 /* Declare the marker procedure. */
2357 oprintf (header_file
, "extern void gt_pch_p_");
2358 output_mangled_typename (header_file
, s
);
2359 oprintf (header_file
,
2360 "\n (void *, void *, gt_pointer_operator, void *);\n");
2362 if (stru
->u
.s
.line
.file
== NULL
)
2364 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2369 if (stru
->kind
== TYPE_LANG_STRUCT
)
2372 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2373 write_local_func_for_structure (s
, ss
, param
);
2376 write_local_func_for_structure (s
, stru
, param
);
2380 /* Write out the 'enum' definition for gt_types_enum. */
2383 write_enum_defn (type_p structures
, type_p param_structs
)
2387 oprintf (header_file
, "\n/* Enumeration of types known. */\n");
2388 oprintf (header_file
, "enum gt_types_enum {\n");
2389 for (s
= structures
; s
; s
= s
->next
)
2390 if (s
->gc_used
== GC_POINTED_TO
2391 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2393 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2394 && s
->u
.s
.line
.file
== NULL
)
2397 oprintf (header_file
, " gt_ggc_e_");
2398 output_mangled_typename (header_file
, s
);
2399 oprintf (header_file
, ", \n");
2401 for (s
= param_structs
; s
; s
= s
->next
)
2402 if (s
->gc_used
== GC_POINTED_TO
)
2404 oprintf (header_file
, " gt_e_");
2405 output_mangled_typename (header_file
, s
);
2406 oprintf (header_file
, ", \n");
2408 oprintf (header_file
, " gt_types_enum_last\n");
2409 oprintf (header_file
, "};\n");
2412 /* Might T contain any non-pointer elements? */
2415 contains_scalar_p (type_p t
)
2423 return contains_scalar_p (t
->u
.a
.p
);
2425 /* Could also check for structures that have no non-pointer
2426 fields, but there aren't enough of those to worry about. */
2431 /* Mangle FN and print it to F. */
2434 put_mangled_filename (outf_p f
, const char *fn
)
2436 const char *name
= get_output_file_name (fn
);
2437 for (; *name
!= 0; name
++)
2438 if (ISALNUM (*name
))
2439 oprintf (f
, "%c", *name
);
2441 oprintf (f
, "%c", '_');
2444 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2445 LASTNAME, and NAME are all strings to insert in various places in
2446 the resulting code. */
2449 finish_root_table (struct flist
*flp
, const char *pfx
, const char *lastname
,
2450 const char *tname
, const char *name
)
2454 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2455 if (fli2
->started_p
)
2457 oprintf (fli2
->f
, " %s\n", lastname
);
2458 oprintf (fli2
->f
, "};\n\n");
2461 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2462 if (fli2
->started_p
)
2464 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2467 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2470 oprintf (base_files
[fnum
],
2471 "extern const struct %s gt_%s_",
2473 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2474 oprintf (base_files
[fnum
], "[];\n");
2480 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2481 oprintf (base_files
[fnum
],
2482 "const struct %s * const %s[] = {\n",
2487 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2488 if (fli2
->started_p
)
2490 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2493 fli2
->started_p
= 0;
2495 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2498 oprintf (base_files
[fnum
], " gt_%s_", pfx
);
2499 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2500 oprintf (base_files
[fnum
], ",\n");
2506 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2508 oprintf (base_files
[fnum
], " NULL\n");
2509 oprintf (base_files
[fnum
], "};\n");
2514 /* Write out to F the table entry and any marker routines needed to
2515 mark NAME as TYPE. The original variable is V, at LINE.
2516 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2517 is nonzero iff we are building the root table for hash table caches. */
2520 write_root (outf_p f
, pair_p v
, type_p type
, const char *name
, int has_length
,
2521 struct fileloc
*line
, const char *if_marked
)
2528 for (fld
= type
->u
.s
.fields
; fld
; fld
= fld
->next
)
2531 const char *desc
= NULL
;
2534 for (o
= fld
->opt
; o
; o
= o
->next
)
2535 if (strcmp (o
->name
, "skip") == 0)
2537 else if (strcmp (o
->name
, "desc") == 0)
2538 desc
= (const char *)o
->info
;
2540 error_at_line (line
,
2541 "field `%s' of global `%s' has unknown option `%s'",
2542 fld
->name
, name
, o
->name
);
2546 else if (desc
&& fld
->type
->kind
== TYPE_UNION
)
2548 pair_p validf
= NULL
;
2551 for (ufld
= fld
->type
->u
.s
.fields
; ufld
; ufld
= ufld
->next
)
2553 const char *tag
= NULL
;
2556 for (oo
= ufld
->opt
; oo
; oo
= oo
->next
)
2557 if (strcmp (oo
->name
, "tag") == 0)
2558 tag
= (const char *)oo
->info
;
2559 if (tag
== NULL
|| strcmp (tag
, desc
) != 0)
2562 error_at_line (line
,
2563 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2564 name
, fld
->name
, validf
->name
,
2565 name
, fld
->name
, ufld
->name
,
2572 newname
= xasprintf ("%s.%s.%s",
2573 name
, fld
->name
, validf
->name
);
2574 write_root (f
, v
, validf
->type
, newname
, 0, line
,
2580 error_at_line (line
,
2581 "global `%s.%s' has `desc' option but is not union",
2586 newname
= xasprintf ("%s.%s", name
, fld
->name
);
2587 write_root (f
, v
, fld
->type
, newname
, 0, line
, if_marked
);
2597 newname
= xasprintf ("%s[0]", name
);
2598 write_root (f
, v
, type
->u
.a
.p
, newname
, has_length
, line
, if_marked
);
2607 oprintf (f
, " {\n");
2608 oprintf (f
, " &%s,\n", name
);
2611 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2613 oprintf (f
, " * (%s)", ap
->u
.a
.len
);
2614 else if (ap
== v
->type
)
2615 oprintf (f
, " * ARRAY_SIZE (%s)", v
->name
);
2617 oprintf (f
, " sizeof (%s", v
->name
);
2618 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2620 oprintf (f
, "),\n");
2624 if (! has_length
&& UNION_OR_STRUCT_P (tp
))
2626 oprintf (f
, " >_ggc_mx_%s,\n", tp
->u
.s
.tag
);
2627 oprintf (f
, " >_pch_nx_%s", tp
->u
.s
.tag
);
2629 else if (! has_length
&& tp
->kind
== TYPE_PARAM_STRUCT
)
2631 oprintf (f
, " >_ggc_m_");
2632 output_mangled_typename (f
, tp
);
2633 oprintf (f
, ",\n >_pch_n_");
2634 output_mangled_typename (f
, tp
);
2637 && (tp
->kind
== TYPE_POINTER
|| UNION_OR_STRUCT_P (tp
)))
2639 oprintf (f
, " >_ggc_ma_%s,\n", name
);
2640 oprintf (f
, " >_pch_na_%s", name
);
2644 error_at_line (line
,
2645 "global `%s' is pointer to unimplemented type",
2649 oprintf (f
, ",\n &%s", if_marked
);
2650 oprintf (f
, "\n },\n");
2656 oprintf (f
, " {\n");
2657 oprintf (f
, " &%s,\n", name
);
2658 oprintf (f
, " 1, \n");
2659 oprintf (f
, " sizeof (%s),\n", v
->name
);
2660 oprintf (f
, " >_ggc_m_S,\n");
2661 oprintf (f
, " (gt_pointer_walker) >_pch_n_S\n");
2662 oprintf (f
, " },\n");
2670 error_at_line (line
,
2671 "global `%s' is unimplemented type",
2676 /* This generates a routine to walk an array. */
2679 write_array (outf_p f
, pair_p v
, const struct write_types_data
*wtd
)
2681 struct walk_type_data d
;
2684 memset (&d
, 0, sizeof (d
));
2690 d
.bitmap
= get_base_file_bitmap (v
->line
.file
);
2693 d
.prev_val
[3] = prevval3
= xasprintf ("&%s", v
->name
);
2695 if (wtd
->param_prefix
)
2697 oprintf (f
, "static void gt_%sa_%s\n", wtd
->param_prefix
, v
->name
);
2699 " (void *, void *, gt_pointer_operator, void *);\n");
2700 oprintf (f
, "static void gt_%sa_%s (void *this_obj ATTRIBUTE_UNUSED,\n",
2701 wtd
->param_prefix
, v
->name
);
2702 oprintf (d
.of
, " void *x_p ATTRIBUTE_UNUSED,\n");
2703 oprintf (d
.of
, " gt_pointer_operator op ATTRIBUTE_UNUSED,\n");
2704 oprintf (d
.of
, " void *cookie ATTRIBUTE_UNUSED)\n");
2705 oprintf (d
.of
, "{\n");
2706 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2707 d
.process_field
= write_types_local_process_field
;
2708 walk_type (v
->type
, &d
);
2709 oprintf (f
, "}\n\n");
2713 oprintf (f
, "static void gt_%sa_%s (void *);\n",
2714 wtd
->prefix
, v
->name
);
2715 oprintf (f
, "static void\ngt_%sa_%s (void *x_p ATTRIBUTE_UNUSED)\n",
2716 wtd
->prefix
, v
->name
);
2718 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2719 d
.process_field
= write_types_process_field
;
2720 walk_type (v
->type
, &d
);
2722 oprintf (f
, "}\n\n");
2725 /* Output a table describing the locations and types of VARIABLES. */
2728 write_roots (pair_p variables
)
2731 struct flist
*flp
= NULL
;
2733 for (v
= variables
; v
; v
= v
->next
)
2735 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2737 const char *length
= NULL
;
2738 int deletable_p
= 0;
2741 for (o
= v
->opt
; o
; o
= o
->next
)
2742 if (strcmp (o
->name
, "length") == 0)
2743 length
= (const char *)o
->info
;
2744 else if (strcmp (o
->name
, "deletable") == 0)
2746 else if (strcmp (o
->name
, "param_is") == 0)
2748 else if (strncmp (o
->name
, "param", 5) == 0
2749 && ISDIGIT (o
->name
[5])
2750 && strcmp (o
->name
+ 6, "_is") == 0)
2752 else if (strcmp (o
->name
, "if_marked") == 0)
2755 error_at_line (&v
->line
,
2756 "global `%s' has unknown option `%s'",
2759 for (fli
= flp
; fli
; fli
= fli
->next
)
2764 fli
= xmalloc (sizeof (*fli
));
2768 fli
->name
= v
->line
.file
;
2771 oprintf (f
, "\n/* GC roots. */\n\n");
2776 && v
->type
->kind
== TYPE_POINTER
2777 && (v
->type
->u
.p
->kind
== TYPE_POINTER
2778 || v
->type
->u
.p
->kind
== TYPE_STRUCT
))
2780 write_array (f
, v
, &ggc_wtd
);
2781 write_array (f
, v
, &pch_wtd
);
2785 for (v
= variables
; v
; v
= v
->next
)
2787 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2793 for (o
= v
->opt
; o
; o
= o
->next
)
2794 if (strcmp (o
->name
, "length") == 0)
2796 else if (strcmp (o
->name
, "deletable") == 0
2797 || strcmp (o
->name
, "if_marked") == 0)
2803 for (fli
= flp
; fli
; fli
= fli
->next
)
2806 if (! fli
->started_p
)
2810 oprintf (f
, "const struct ggc_root_tab gt_ggc_r_");
2811 put_mangled_filename (f
, v
->line
.file
);
2812 oprintf (f
, "[] = {\n");
2815 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2818 finish_root_table (flp
, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2821 for (v
= variables
; v
; v
= v
->next
)
2823 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2828 for (o
= v
->opt
; o
; o
= o
->next
)
2829 if (strcmp (o
->name
, "deletable") == 0)
2831 else if (strcmp (o
->name
, "if_marked") == 0)
2837 for (fli
= flp
; fli
; fli
= fli
->next
)
2840 if (! fli
->started_p
)
2844 oprintf (f
, "const struct ggc_root_tab gt_ggc_rd_");
2845 put_mangled_filename (f
, v
->line
.file
);
2846 oprintf (f
, "[] = {\n");
2849 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2853 finish_root_table (flp
, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2854 "gt_ggc_deletable_rtab");
2856 for (v
= variables
; v
; v
= v
->next
)
2858 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2860 const char *if_marked
= NULL
;
2864 for (o
= v
->opt
; o
; o
= o
->next
)
2865 if (strcmp (o
->name
, "length") == 0)
2867 else if (strcmp (o
->name
, "if_marked") == 0)
2868 if_marked
= (const char *) o
->info
;
2870 if (if_marked
== NULL
)
2873 if (v
->type
->kind
!= TYPE_POINTER
2874 || v
->type
->u
.p
->kind
!= TYPE_PARAM_STRUCT
2875 || v
->type
->u
.p
->u
.param_struct
.stru
!= find_structure ("htab", 0))
2877 error_at_line (&v
->line
, "if_marked option used but not hash table");
2881 for (fli
= flp
; fli
; fli
= fli
->next
)
2884 if (! fli
->started_p
)
2888 oprintf (f
, "const struct ggc_cache_tab gt_ggc_rc_");
2889 put_mangled_filename (f
, v
->line
.file
);
2890 oprintf (f
, "[] = {\n");
2893 write_root (f
, v
, v
->type
->u
.p
->u
.param_struct
.param
[0],
2894 v
->name
, length_p
, &v
->line
, if_marked
);
2897 finish_root_table (flp
, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2898 "gt_ggc_cache_rtab");
2900 for (v
= variables
; v
; v
= v
->next
)
2902 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2905 int if_marked_p
= 0;
2908 for (o
= v
->opt
; o
; o
= o
->next
)
2909 if (strcmp (o
->name
, "length") == 0)
2911 else if (strcmp (o
->name
, "if_marked") == 0)
2917 for (fli
= flp
; fli
; fli
= fli
->next
)
2920 if (! fli
->started_p
)
2924 oprintf (f
, "const struct ggc_root_tab gt_pch_rc_");
2925 put_mangled_filename (f
, v
->line
.file
);
2926 oprintf (f
, "[] = {\n");
2929 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2932 finish_root_table (flp
, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2933 "gt_pch_cache_rtab");
2935 for (v
= variables
; v
; v
= v
->next
)
2937 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2942 for (o
= v
->opt
; o
; o
= o
->next
)
2943 if (strcmp (o
->name
, "deletable") == 0
2944 || strcmp (o
->name
, "if_marked") == 0)
2950 if (! contains_scalar_p (v
->type
))
2953 for (fli
= flp
; fli
; fli
= fli
->next
)
2956 if (! fli
->started_p
)
2960 oprintf (f
, "const struct ggc_root_tab gt_pch_rs_");
2961 put_mangled_filename (f
, v
->line
.file
);
2962 oprintf (f
, "[] = {\n");
2965 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2969 finish_root_table (flp
, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2970 "gt_pch_scalar_rtab");
2974 extern int main (int argc
, char **argv
);
2976 main(int argc ATTRIBUTE_UNUSED
, char **argv ATTRIBUTE_UNUSED
)
2979 static struct fileloc pos
= { __FILE__
, __LINE__
};
2984 srcdir_len
= strlen (srcdir
);
2986 do_scalar_typedef ("CUMULATIVE_ARGS", &pos
);
2987 do_scalar_typedef ("REAL_VALUE_TYPE", &pos
);
2988 do_scalar_typedef ("uint8", &pos
);
2989 do_scalar_typedef ("jword", &pos
);
2990 do_scalar_typedef ("JCF_u2", &pos
);
2991 #ifdef USE_MAPPED_LOCATION
2992 do_scalar_typedef ("location_t", &pos
);
2993 do_scalar_typedef ("source_locus", &pos
);
2995 do_scalar_typedef ("void", &pos
);
2997 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos
)), &pos
);
2999 do_typedef ("HARD_REG_SET", create_array (
3000 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3003 for (i
= 0; i
< NUM_GT_FILES
; i
++)
3006 /* Omit if already seen. */
3007 for (j
= 0; j
< i
; j
++)
3009 if (!strcmp (all_files
[i
], all_files
[j
]))
3016 parse_file (all_files
[i
]);
3017 #ifndef USE_MAPPED_LOCATION
3018 /* temporary kludge - gengtype doesn't handle conditionals.
3019 Manually add source_locus *after* we've processed input.h. */
3021 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos
)), &pos
);
3028 set_gc_used (variables
);
3031 write_enum_defn (structures
, param_structs
);
3032 write_types (structures
, param_structs
, &ggc_wtd
);
3033 write_types (structures
, param_structs
, &pch_wtd
);
3034 write_local (structures
, param_structs
);
3035 write_roots (variables
);
3037 close_output_files ();
3039 return (hit_error
!= 0);