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", "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",
1115 const char *const *ifp
;
1116 outf_p gtype_desc_c
;
1118 gtype_desc_c
= create_file ("GCC", "gtype-desc.c");
1119 for (ifp
= ifiles
; *ifp
; ifp
++)
1120 oprintf (gtype_desc_c
, "#include \"%s\"\n", *ifp
);
1124 /* Determine the pathname to F relative to $(srcdir). */
1127 get_file_basename (const char *f
)
1129 const char *basename
;
1132 basename
= strrchr (f
, '/');
1139 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1145 s1
= basename
- strlen (lang_dir_names
[i
]) - 1;
1146 s2
= lang_dir_names
[i
];
1149 if (l1
>= l2
&& !memcmp (s1
, s2
, l2
))
1152 if ((basename
- f
- 1) != srcdir_len
)
1153 abort (); /* Match is wrong - should be preceded by $srcdir. */
1161 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1162 INPUT_FILE is used by <lang>.
1164 This function should be written to assume that a file _is_ used
1165 if the situation is unclear. If it wrongly assumes a file _is_ used,
1166 a linker error will result. If it wrongly assumes a file _is not_ used,
1167 some GC roots may be missed, which is a much harder-to-debug problem. */
1170 get_base_file_bitmap (const char *input_file
)
1172 const char *basename
= get_file_basename (input_file
);
1173 const char *slashpos
= strchr (basename
, '/');
1181 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1182 if ((size_t)(slashpos
- basename
) == strlen (lang_dir_names
[i
])
1183 && memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0)
1185 /* It's in a language directory, set that language. */
1190 abort (); /* Should have found the language. */
1193 /* If it's in any config-lang.in, then set for the languages
1198 for (j
= 0; j
< NUM_LANG_FILES
; j
++)
1200 if (!strcmp(input_file
, lang_files
[j
]))
1202 for (k
= 0; k
< NUM_BASE_FILES
; k
++)
1204 if (!strcmp(lang_dir_names
[k
], langs_for_lang_files
[j
]))
1210 /* Otherwise, set all languages. */
1212 bitmap
= (1 << NUM_BASE_FILES
) - 1;
1217 /* An output file, suitable for definitions, that can see declarations
1218 made in INPUT_FILE and is linked into every language that uses
1222 get_output_file_with_visibility (const char *input_file
)
1226 const char *basename
;
1227 const char *for_name
;
1228 const char *output_name
;
1230 /* This can happen when we need a file with visibility on a
1231 structure that we've never seen. We have to just hope that it's
1232 globally visible. */
1233 if (input_file
== NULL
)
1234 input_file
= "system.h";
1236 /* Determine the output file name. */
1237 basename
= get_file_basename (input_file
);
1239 len
= strlen (basename
);
1240 if ((len
> 2 && memcmp (basename
+len
-2, ".c", 2) == 0)
1241 || (len
> 2 && memcmp (basename
+len
-2, ".y", 2) == 0)
1242 || (len
> 3 && memcmp (basename
+len
-3, ".in", 3) == 0))
1246 output_name
= s
= xasprintf ("gt-%s", basename
);
1247 for (; *s
!= '.'; s
++)
1248 if (! ISALNUM (*s
) && *s
!= '-')
1250 memcpy (s
, ".h", sizeof (".h"));
1251 for_name
= basename
;
1253 else if (strcmp (basename
, "c-common.h") == 0)
1254 output_name
= "gt-c-common.h", for_name
= "c-common.c";
1255 else if (strcmp (basename
, "c-tree.h") == 0)
1256 output_name
= "gt-c-decl.h", for_name
= "c-decl.c";
1261 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1262 if (memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0
1263 && basename
[strlen(lang_dir_names
[i
])] == '/')
1264 return base_files
[i
];
1266 output_name
= "gtype-desc.c";
1270 /* Look through to see if we've ever seen this output filename before. */
1271 for (r
= output_files
; r
; r
= r
->next
)
1272 if (strcmp (r
->name
, output_name
) == 0)
1275 /* If not, create it. */
1276 r
= create_file (for_name
, output_name
);
1281 /* The name of an output file, suitable for definitions, that can see
1282 declarations made in INPUT_FILE and is linked into every language
1283 that uses INPUT_FILE. */
1286 get_output_file_name (const char *input_file
)
1288 return get_output_file_with_visibility (input_file
)->name
;
1291 /* Copy the output to its final destination,
1292 but don't unnecessarily change modification times. */
1295 close_output_files (void)
1299 for (of
= output_files
; of
; of
= of
->next
)
1303 newfile
= fopen (of
->name
, "r");
1304 if (newfile
!= NULL
)
1309 for (i
= 0; i
< of
->bufused
; i
++)
1312 ch
= fgetc (newfile
);
1313 if (ch
== EOF
|| ch
!= (unsigned char) of
->buf
[i
])
1316 no_write_p
= i
== of
->bufused
&& fgetc (newfile
) == EOF
;
1323 newfile
= fopen (of
->name
, "w");
1324 if (newfile
== NULL
)
1326 perror ("opening output file");
1329 if (fwrite (of
->buf
, 1, of
->bufused
, newfile
) != of
->bufused
)
1331 perror ("writing output file");
1334 if (fclose (newfile
) != 0)
1336 perror ("closing output file");
1349 struct walk_type_data
;
1351 /* For scalars and strings, given the item in 'val'.
1352 For structures, given a pointer to the item in 'val'.
1353 For misc. pointers, given the item in 'val'.
1355 typedef void (*process_field_fn
)
1356 (type_p f
, const struct walk_type_data
*p
);
1357 typedef void (*func_name_fn
)
1358 (type_p s
, const struct walk_type_data
*p
);
1360 /* Parameters for write_types. */
1362 struct write_types_data
1365 const char *param_prefix
;
1366 const char *subfield_marker_routine
;
1367 const char *marker_routine
;
1368 const char *reorder_note_routine
;
1369 const char *comment
;
1372 static void output_escaped_param (struct walk_type_data
*d
,
1373 const char *, const char *);
1374 static void output_mangled_typename (outf_p
, type_p
);
1375 static void walk_type (type_p t
, struct walk_type_data
*d
);
1376 static void write_func_for_structure
1377 (type_p orig_s
, type_p s
, type_p
* param
,
1378 const struct write_types_data
*wtd
);
1379 static void write_types_process_field
1380 (type_p f
, const struct walk_type_data
*d
);
1381 static void write_types (type_p structures
,
1382 type_p param_structs
,
1383 const struct write_types_data
*wtd
);
1384 static void write_types_local_process_field
1385 (type_p f
, const struct walk_type_data
*d
);
1386 static void write_local_func_for_structure
1387 (type_p orig_s
, type_p s
, type_p
* param
);
1388 static void write_local (type_p structures
,
1389 type_p param_structs
);
1390 static void write_enum_defn (type_p structures
, type_p param_structs
);
1391 static int contains_scalar_p (type_p t
);
1392 static void put_mangled_filename (outf_p
, const char *);
1393 static void finish_root_table (struct flist
*flp
, const char *pfx
,
1394 const char *tname
, const char *lastname
,
1396 static void write_root (outf_p
, pair_p
, type_p
, const char *, int,
1397 struct fileloc
*, const char *);
1398 static void write_array (outf_p f
, pair_p v
,
1399 const struct write_types_data
*wtd
);
1400 static void write_roots (pair_p
);
1402 /* Parameters for walk_type. */
1404 struct walk_type_data
1406 process_field_fn process_field
;
1411 const char *prev_val
[4];
1414 struct fileloc
*line
;
1419 const char *reorder_fn
;
1421 bool fn_wants_lvalue
;
1424 /* Print a mangled name representing T to OF. */
1427 output_mangled_typename (outf_p of
, type_p t
)
1431 else switch (t
->kind
)
1435 output_mangled_typename (of
, t
->u
.p
);
1445 case TYPE_LANG_STRUCT
:
1446 oprintf (of
, "%lu%s", (unsigned long) strlen (t
->u
.s
.tag
), t
->u
.s
.tag
);
1448 case TYPE_PARAM_STRUCT
:
1451 for (i
= 0; i
< NUM_PARAM
; i
++)
1452 if (t
->u
.param_struct
.param
[i
] != NULL
)
1453 output_mangled_typename (of
, t
->u
.param_struct
.param
[i
]);
1454 output_mangled_typename (of
, t
->u
.param_struct
.stru
);
1462 /* Print PARAM to D->OF processing escapes. D->VAL references the
1463 current object, D->PREV_VAL the object containing the current
1464 object, ONAME is the name of the option and D->LINE is used to
1465 print error messages. */
1468 output_escaped_param (struct walk_type_data
*d
, const char *param
,
1473 for (p
= param
; *p
; p
++)
1475 oprintf (d
->of
, "%c", *p
);
1479 oprintf (d
->of
, "(%s)", d
->prev_val
[2]);
1482 oprintf (d
->of
, "(%s)", d
->prev_val
[0]);
1485 oprintf (d
->of
, "(%s)", d
->prev_val
[1]);
1489 const char *pp
= d
->val
+ strlen (d
->val
);
1490 while (pp
[-1] == ']')
1493 oprintf (d
->of
, "%s", pp
);
1497 error_at_line (d
->line
, "`%s' option contains bad escape %c%c",
1502 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1503 which is of type T. Write code to D->OF to constrain execution (at
1504 the point that D->PROCESS_FIELD is called) to the appropriate
1505 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1506 pointers to those objects. D->PREV_VAL lists the objects
1507 containing the current object, D->OPT is a list of options to
1508 apply, D->INDENT is the current indentation level, D->LINE is used
1509 to print error messages, D->BITMAP indicates which languages to
1510 print the structure for, and D->PARAM is the current parameter
1511 (from an enclosing param_is option). */
1514 walk_type (type_p t
, struct walk_type_data
*d
)
1516 const char *length
= NULL
;
1517 const char *desc
= NULL
;
1518 int maybe_undef_p
= 0;
1519 int use_param_num
= -1;
1520 int use_params_p
= 0;
1522 const struct nested_ptr_data
*nested_ptr_d
= NULL
;
1524 d
->needs_cast_p
= false;
1525 for (oo
= d
->opt
; oo
; oo
= oo
->next
)
1526 if (strcmp (oo
->name
, "length") == 0)
1527 length
= (const char *)oo
->info
;
1528 else if (strcmp (oo
->name
, "maybe_undef") == 0)
1530 else if (strncmp (oo
->name
, "use_param", 9) == 0
1531 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1532 use_param_num
= oo
->name
[9] == '\0' ? 0 : oo
->name
[9] - '0';
1533 else if (strcmp (oo
->name
, "use_params") == 0)
1535 else if (strcmp (oo
->name
, "desc") == 0)
1536 desc
= (const char *)oo
->info
;
1537 else if (strcmp (oo
->name
, "nested_ptr") == 0)
1538 nested_ptr_d
= (const struct nested_ptr_data
*) oo
->info
;
1539 else if (strcmp (oo
->name
, "dot") == 0)
1541 else if (strcmp (oo
->name
, "tag") == 0)
1543 else if (strcmp (oo
->name
, "special") == 0)
1545 else if (strcmp (oo
->name
, "skip") == 0)
1547 else if (strcmp (oo
->name
, "default") == 0)
1549 else if (strcmp (oo
->name
, "descbits") == 0)
1551 else if (strcmp (oo
->name
, "param_is") == 0)
1553 else if (strncmp (oo
->name
, "param", 5) == 0
1554 && ISDIGIT (oo
->name
[5])
1555 && strcmp (oo
->name
+ 6, "_is") == 0)
1557 else if (strcmp (oo
->name
, "chain_next") == 0)
1559 else if (strcmp (oo
->name
, "chain_prev") == 0)
1561 else if (strcmp (oo
->name
, "reorder") == 0)
1564 error_at_line (d
->line
, "unknown option `%s'\n", oo
->name
);
1571 int pointer_p
= t
->kind
== TYPE_POINTER
;
1575 if (! UNION_OR_STRUCT_P (t
))
1576 error_at_line (d
->line
, "`use_params' option on unimplemented type");
1578 t
= find_param_structure (t
, d
->param
);
1580 t
= create_pointer (t
);
1583 if (use_param_num
!= -1)
1585 if (d
->param
!= NULL
&& d
->param
[use_param_num
] != NULL
)
1587 type_p nt
= d
->param
[use_param_num
];
1589 if (t
->kind
== TYPE_ARRAY
)
1590 nt
= create_array (nt
, t
->u
.a
.len
);
1591 else if (length
!= NULL
&& t
->kind
== TYPE_POINTER
)
1592 nt
= create_pointer (nt
);
1593 d
->needs_cast_p
= (t
->kind
!= TYPE_POINTER
1594 && (nt
->kind
== TYPE_POINTER
1595 || nt
->kind
== TYPE_STRING
));
1599 error_at_line (d
->line
, "no parameter defined for `%s'",
1604 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
1606 error_at_line (d
->line
,
1607 "field `%s' has invalid option `maybe_undef_p'\n",
1616 d
->process_field (t
, d
);
1622 && t
->u
.p
->u
.s
.line
.file
== NULL
)
1624 oprintf (d
->of
, "%*sif (%s) abort();\n", d
->indent
, "", d
->val
);
1630 if (! UNION_OR_STRUCT_P (t
->u
.p
)
1631 && t
->u
.p
->kind
!= TYPE_PARAM_STRUCT
)
1633 error_at_line (d
->line
,
1634 "field `%s' is pointer to unimplemented type",
1641 const char *oldprevval2
= d
->prev_val
[2];
1643 if (! UNION_OR_STRUCT_P (nested_ptr_d
->type
))
1645 error_at_line (d
->line
,
1646 "field `%s' has invalid "
1647 "option `nested_ptr'\n",
1652 d
->prev_val
[2] = d
->val
;
1653 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1655 d
->val
= xasprintf ("x%d", d
->counter
++);
1656 oprintf (d
->of
, "%*s%s %s * %s%s =\n", d
->indent
, "",
1657 (nested_ptr_d
->type
->kind
== TYPE_UNION
1658 ? "union" : "struct"),
1659 nested_ptr_d
->type
->u
.s
.tag
,
1660 d
->fn_wants_lvalue
? "" : "const ",
1662 oprintf (d
->of
, "%*s", d
->indent
+ 2, "");
1663 output_escaped_param (d
, nested_ptr_d
->convert_from
,
1665 oprintf (d
->of
, ";\n");
1667 d
->process_field (nested_ptr_d
->type
, d
);
1669 if (d
->fn_wants_lvalue
)
1671 oprintf (d
->of
, "%*s%s = ", d
->indent
, "",
1673 d
->prev_val
[2] = d
->val
;
1674 output_escaped_param (d
, nested_ptr_d
->convert_to
,
1676 oprintf (d
->of
, ";\n");
1680 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1681 d
->val
= d
->prev_val
[2];
1682 d
->prev_val
[2] = oldprevval2
;
1685 d
->process_field (t
->u
.p
, d
);
1689 int loopcounter
= d
->counter
++;
1690 const char *oldval
= d
->val
;
1691 const char *oldprevval3
= d
->prev_val
[3];
1694 oprintf (d
->of
, "%*sif (%s != NULL) {\n", d
->indent
, "", d
->val
);
1696 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1697 oprintf (d
->of
, "%*sfor (i%d = 0; i%d < (size_t)(", d
->indent
, "",
1698 loopcounter
, loopcounter
);
1699 output_escaped_param (d
, length
, "length");
1700 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1702 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1704 d
->prev_val
[3] = oldval
;
1705 walk_type (t
->u
.p
, d
);
1708 d
->prev_val
[3] = oldprevval3
;
1711 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1712 d
->process_field(t
, d
);
1714 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1721 int loopcounter
= d
->counter
++;
1722 const char *oldval
= d
->val
;
1725 /* If it's an array of scalars, we optimize by not generating
1727 if (t
->u
.a
.p
->kind
== TYPE_SCALAR
)
1730 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1732 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1733 oprintf (d
->of
, "%*sfor (i%d = 0; i%d < (size_t)(", d
->indent
, "",
1734 loopcounter
, loopcounter
);
1736 output_escaped_param (d
, length
, "length");
1738 oprintf (d
->of
, "%s", t
->u
.a
.len
);
1739 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1741 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1743 walk_type (t
->u
.a
.p
, d
);
1748 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1750 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1758 const char *oldval
= d
->val
;
1759 const char *oldprevval1
= d
->prev_val
[1];
1760 const char *oldprevval2
= d
->prev_val
[2];
1761 const int union_p
= t
->kind
== TYPE_UNION
;
1762 int seen_default_p
= 0;
1765 if (! t
->u
.s
.line
.file
)
1766 error_at_line (d
->line
, "incomplete structure `%s'", t
->u
.s
.tag
);
1768 if ((d
->bitmap
& t
->u
.s
.bitmap
) != d
->bitmap
)
1770 error_at_line (d
->line
,
1771 "structure `%s' defined for mismatching languages",
1773 error_at_line (&t
->u
.s
.line
, "one structure defined here");
1776 /* Some things may also be defined in the structure's options. */
1777 for (o
= t
->u
.s
.opt
; o
; o
= o
->next
)
1778 if (! desc
&& strcmp (o
->name
, "desc") == 0)
1779 desc
= (const char *)o
->info
;
1781 d
->prev_val
[2] = oldval
;
1782 d
->prev_val
[1] = oldprevval2
;
1787 error_at_line (d
->line
, "missing `desc' option for union `%s'",
1791 oprintf (d
->of
, "%*sswitch (", d
->indent
, "");
1792 output_escaped_param (d
, desc
, "desc");
1793 oprintf (d
->of
, ")\n");
1795 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1797 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
1800 const char *dot
= ".";
1801 const char *tagid
= NULL
;
1804 int use_param_p
= 0;
1807 d
->reorder_fn
= NULL
;
1808 for (oo
= f
->opt
; oo
; oo
= oo
->next
)
1809 if (strcmp (oo
->name
, "dot") == 0)
1810 dot
= (const char *)oo
->info
;
1811 else if (strcmp (oo
->name
, "tag") == 0)
1812 tagid
= (const char *)oo
->info
;
1813 else if (strcmp (oo
->name
, "skip") == 0)
1815 else if (strcmp (oo
->name
, "default") == 0)
1817 else if (strcmp (oo
->name
, "reorder") == 0)
1818 d
->reorder_fn
= (const char *)oo
->info
;
1819 else if (strncmp (oo
->name
, "use_param", 9) == 0
1820 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1826 if (union_p
&& tagid
)
1828 oprintf (d
->of
, "%*scase %s:\n", d
->indent
, "", tagid
);
1831 else if (union_p
&& default_p
)
1833 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1837 else if (! union_p
&& (default_p
|| tagid
))
1838 error_at_line (d
->line
,
1839 "can't use `%s' outside a union on field `%s'",
1840 default_p
? "default" : "tag", f
->name
);
1841 else if (union_p
&& ! (default_p
|| tagid
)
1842 && f
->type
->kind
== TYPE_SCALAR
)
1845 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1846 d
->line
->file
, d
->line
->line
, f
->name
);
1849 else if (union_p
&& ! (default_p
|| tagid
))
1850 error_at_line (d
->line
,
1851 "field `%s' is missing `tag' or `default' option",
1855 d
->val
= newval
= xasprintf ("%s%s%s", oldval
, dot
, f
->name
);
1857 d
->used_length
= false;
1859 if (union_p
&& use_param_p
&& d
->param
== NULL
)
1860 oprintf (d
->of
, "%*sabort();\n", d
->indent
, "");
1862 walk_type (f
->type
, d
);
1868 oprintf (d
->of
, "%*sbreak;\n", d
->indent
, "");
1872 d
->reorder_fn
= NULL
;
1875 d
->prev_val
[1] = oldprevval1
;
1876 d
->prev_val
[2] = oldprevval2
;
1878 if (union_p
&& ! seen_default_p
)
1880 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1881 oprintf (d
->of
, "%*s break;\n", d
->indent
, "");
1885 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1891 case TYPE_LANG_STRUCT
:
1894 for (nt
= t
->u
.s
.lang_struct
; nt
; nt
= nt
->next
)
1895 if ((d
->bitmap
& nt
->u
.s
.bitmap
) == d
->bitmap
)
1898 error_at_line (d
->line
, "structure `%s' differs between languages",
1905 case TYPE_PARAM_STRUCT
:
1907 type_p
*oldparam
= d
->param
;
1909 d
->param
= t
->u
.param_struct
.param
;
1910 walk_type (t
->u
.param_struct
.stru
, d
);
1911 d
->param
= oldparam
;
1920 /* process_field routine for marking routines. */
1923 write_types_process_field (type_p f
, const struct walk_type_data
*d
)
1925 const struct write_types_data
*wtd
;
1926 const char *cast
= d
->needs_cast_p
? "(void *)" : "";
1927 wtd
= (const struct write_types_data
*) d
->cookie
;
1932 oprintf (d
->of
, "%*s%s (%s%s", d
->indent
, "",
1933 wtd
->subfield_marker_routine
, cast
, d
->val
);
1934 if (wtd
->param_prefix
)
1936 oprintf (d
->of
, ", %s", d
->prev_val
[3]);
1939 oprintf (d
->of
, ", gt_%s_", wtd
->param_prefix
);
1940 output_mangled_typename (d
->of
, d
->orig_s
);
1943 oprintf (d
->of
, ", gt_%sa_%s", wtd
->param_prefix
, d
->prev_val
[0]);
1945 oprintf (d
->of
, ");\n");
1946 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1947 oprintf (d
->of
, "%*s%s (%s%s, %s, %s);\n", d
->indent
, "",
1948 wtd
->reorder_note_routine
, cast
, d
->val
,
1949 d
->prev_val
[3], d
->reorder_fn
);
1953 if (wtd
->param_prefix
== NULL
)
1958 case TYPE_LANG_STRUCT
:
1959 case TYPE_PARAM_STRUCT
:
1960 oprintf (d
->of
, "%*sgt_%s_", d
->indent
, "", wtd
->prefix
);
1961 output_mangled_typename (d
->of
, f
);
1962 oprintf (d
->of
, " (%s%s);\n", cast
, d
->val
);
1963 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1964 oprintf (d
->of
, "%*s%s (%s%s, %s%s, %s);\n", d
->indent
, "",
1965 wtd
->reorder_note_routine
, cast
, d
->val
, cast
, d
->val
,
1977 /* For S, a structure that's part of ORIG_S, and using parameters
1978 PARAM, write out a routine that:
1979 - Takes a parameter, a void * but actually of type *S
1980 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1981 field of S or its substructures and (in some cases) things
1982 that are pointed to by S.
1986 write_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
,
1987 const struct write_types_data
*wtd
)
1989 const char *fn
= s
->u
.s
.line
.file
;
1991 const char *chain_next
= NULL
;
1992 const char *chain_prev
= NULL
;
1994 struct walk_type_data d
;
1996 /* This is a hack, and not the good kind either. */
1997 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
1998 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
1999 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
2000 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2002 memset (&d
, 0, sizeof (d
));
2003 d
.of
= get_output_file_with_visibility (fn
);
2005 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2006 if (strcmp (opt
->name
, "chain_next") == 0)
2007 chain_next
= (const char *) opt
->info
;
2008 else if (strcmp (opt
->name
, "chain_prev") == 0)
2009 chain_prev
= (const char *) opt
->info
;
2011 if (chain_prev
!= NULL
&& chain_next
== NULL
)
2012 error_at_line (&s
->u
.s
.line
, "chain_prev without chain_next");
2014 d
.process_field
= write_types_process_field
;
2018 d
.line
= &s
->u
.s
.line
;
2019 d
.bitmap
= s
->u
.s
.bitmap
;
2021 d
.prev_val
[0] = "*x";
2022 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2023 d
.prev_val
[3] = "x";
2026 oprintf (d
.of
, "\n");
2027 oprintf (d
.of
, "void\n");
2029 oprintf (d
.of
, "gt_%sx_%s", wtd
->prefix
, orig_s
->u
.s
.tag
);
2032 oprintf (d
.of
, "gt_%s_", wtd
->prefix
);
2033 output_mangled_typename (d
.of
, orig_s
);
2035 oprintf (d
.of
, " (void *x_p)\n");
2036 oprintf (d
.of
, "{\n");
2037 oprintf (d
.of
, " %s %s * %sx = (%s %s *)x_p;\n",
2038 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2039 chain_next
== NULL
? "const " : "",
2040 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2041 if (chain_next
!= NULL
)
2042 oprintf (d
.of
, " %s %s * xlimit = x;\n",
2043 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2044 if (chain_next
== NULL
)
2046 oprintf (d
.of
, " if (%s (x", wtd
->marker_routine
);
2047 if (wtd
->param_prefix
)
2049 oprintf (d
.of
, ", x, gt_%s_", wtd
->param_prefix
);
2050 output_mangled_typename (d
.of
, orig_s
);
2052 oprintf (d
.of
, "))\n");
2056 oprintf (d
.of
, " while (%s (xlimit", wtd
->marker_routine
);
2057 if (wtd
->param_prefix
)
2059 oprintf (d
.of
, ", xlimit, gt_%s_", wtd
->param_prefix
);
2060 output_mangled_typename (d
.of
, orig_s
);
2062 oprintf (d
.of
, "))\n");
2063 oprintf (d
.of
, " xlimit = (");
2064 d
.prev_val
[2] = "*xlimit";
2065 output_escaped_param (&d
, chain_next
, "chain_next");
2066 oprintf (d
.of
, ");\n");
2067 if (chain_prev
!= NULL
)
2069 oprintf (d
.of
, " if (x != xlimit)\n");
2070 oprintf (d
.of
, " for (;;)\n");
2071 oprintf (d
.of
, " {\n");
2072 oprintf (d
.of
, " %s %s * const xprev = (",
2073 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2075 d
.prev_val
[2] = "*x";
2076 output_escaped_param (&d
, chain_prev
, "chain_prev");
2077 oprintf (d
.of
, ");\n");
2078 oprintf (d
.of
, " if (xprev == NULL) break;\n");
2079 oprintf (d
.of
, " x = xprev;\n");
2080 oprintf (d
.of
, " (void) %s (xprev",
2081 wtd
->marker_routine
);
2082 if (wtd
->param_prefix
)
2084 oprintf (d
.of
, ", xprev, gt_%s_", wtd
->param_prefix
);
2085 output_mangled_typename (d
.of
, orig_s
);
2087 oprintf (d
.of
, ");\n");
2088 oprintf (d
.of
, " }\n");
2090 oprintf (d
.of
, " while (x != xlimit)\n");
2092 oprintf (d
.of
, " {\n");
2094 d
.prev_val
[2] = "*x";
2098 if (chain_next
!= NULL
)
2100 oprintf (d
.of
, " x = (");
2101 output_escaped_param (&d
, chain_next
, "chain_next");
2102 oprintf (d
.of
, ");\n");
2105 oprintf (d
.of
, " }\n");
2106 oprintf (d
.of
, "}\n");
2109 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2112 write_types (type_p structures
, type_p param_structs
,
2113 const struct write_types_data
*wtd
)
2117 oprintf (header_file
, "\n/* %s*/\n", wtd
->comment
);
2118 for (s
= structures
; s
; s
= s
->next
)
2119 if (s
->gc_used
== GC_POINTED_TO
2120 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2124 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2125 && s
->u
.s
.line
.file
== NULL
)
2128 oprintf (header_file
, "#define gt_%s_", wtd
->prefix
);
2129 output_mangled_typename (header_file
, s
);
2130 oprintf (header_file
, "(X) do { \\\n");
2131 oprintf (header_file
,
2132 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd
->prefix
,
2134 oprintf (header_file
,
2137 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2138 if (strcmp (opt
->name
, "ptr_alias") == 0)
2140 type_p t
= (type_p
) opt
->info
;
2141 if (t
->kind
== TYPE_STRUCT
2142 || t
->kind
== TYPE_UNION
2143 || t
->kind
== TYPE_LANG_STRUCT
)
2144 oprintf (header_file
,
2145 "#define gt_%sx_%s gt_%sx_%s\n",
2146 wtd
->prefix
, s
->u
.s
.tag
, wtd
->prefix
, t
->u
.s
.tag
);
2148 error_at_line (&s
->u
.s
.line
,
2149 "structure alias is not a structure");
2155 /* Declare the marker procedure only once. */
2156 oprintf (header_file
,
2157 "extern void gt_%sx_%s (void *);\n",
2158 wtd
->prefix
, s
->u
.s
.tag
);
2160 if (s
->u
.s
.line
.file
== NULL
)
2162 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2167 if (s
->kind
== TYPE_LANG_STRUCT
)
2170 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2171 write_func_for_structure (s
, ss
, NULL
, wtd
);
2174 write_func_for_structure (s
, s
, NULL
, wtd
);
2177 for (s
= param_structs
; s
; s
= s
->next
)
2178 if (s
->gc_used
== GC_POINTED_TO
)
2180 type_p
* param
= s
->u
.param_struct
.param
;
2181 type_p stru
= s
->u
.param_struct
.stru
;
2183 /* Declare the marker procedure. */
2184 oprintf (header_file
, "extern void gt_%s_", wtd
->prefix
);
2185 output_mangled_typename (header_file
, s
);
2186 oprintf (header_file
, " (void *);\n");
2188 if (stru
->u
.s
.line
.file
== NULL
)
2190 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2195 if (stru
->kind
== TYPE_LANG_STRUCT
)
2198 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2199 write_func_for_structure (s
, ss
, param
, wtd
);
2202 write_func_for_structure (s
, stru
, param
, wtd
);
2206 static const struct write_types_data ggc_wtd
=
2208 "ggc_m", NULL
, "ggc_mark", "ggc_test_and_set_mark", NULL
,
2209 "GC marker procedures. "
2212 static const struct write_types_data pch_wtd
=
2214 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2215 "gt_pch_note_reorder",
2216 "PCH type-walking procedures. "
2219 /* Write out the local pointer-walking routines. */
2221 /* process_field routine for local pointer-walking. */
2224 write_types_local_process_field (type_p f
, const struct walk_type_data
*d
)
2231 case TYPE_LANG_STRUCT
:
2232 case TYPE_PARAM_STRUCT
:
2234 oprintf (d
->of
, "%*sif ((void *)(%s) == this_obj)\n", d
->indent
, "",
2236 oprintf (d
->of
, "%*s op (&(%s), cookie);\n", d
->indent
, "", d
->val
);
2247 /* For S, a structure that's part of ORIG_S, and using parameters
2248 PARAM, write out a routine that:
2249 - Is of type gt_note_pointers
2250 - Calls PROCESS_FIELD on each field of S or its substructures.
2254 write_local_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
)
2256 const char *fn
= s
->u
.s
.line
.file
;
2258 struct walk_type_data d
;
2260 /* This is a hack, and not the good kind either. */
2261 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
2262 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
2263 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
2264 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2266 memset (&d
, 0, sizeof (d
));
2267 d
.of
= get_output_file_with_visibility (fn
);
2269 d
.process_field
= write_types_local_process_field
;
2271 d
.line
= &s
->u
.s
.line
;
2272 d
.bitmap
= s
->u
.s
.bitmap
;
2274 d
.prev_val
[0] = d
.prev_val
[2] = "*x";
2275 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2276 d
.prev_val
[3] = "x";
2278 d
.fn_wants_lvalue
= true;
2280 oprintf (d
.of
, "\n");
2281 oprintf (d
.of
, "void\n");
2282 oprintf (d
.of
, "gt_pch_p_");
2283 output_mangled_typename (d
.of
, orig_s
);
2284 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");
2285 oprintf (d
.of
, "{\n");
2286 oprintf (d
.of
, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2287 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2288 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2291 oprintf (d
.of
, "}\n");
2294 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2297 write_local (type_p structures
, type_p param_structs
)
2301 oprintf (header_file
, "\n/* Local pointer-walking routines. */\n");
2302 for (s
= structures
; s
; s
= s
->next
)
2303 if (s
->gc_used
== GC_POINTED_TO
2304 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2308 if (s
->u
.s
.line
.file
== NULL
)
2311 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2312 if (strcmp (opt
->name
, "ptr_alias") == 0)
2314 type_p t
= (type_p
) opt
->info
;
2315 if (t
->kind
== TYPE_STRUCT
2316 || t
->kind
== TYPE_UNION
2317 || t
->kind
== TYPE_LANG_STRUCT
)
2319 oprintf (header_file
, "#define gt_pch_p_");
2320 output_mangled_typename (header_file
, s
);
2321 oprintf (header_file
, " gt_pch_p_");
2322 output_mangled_typename (header_file
, t
);
2323 oprintf (header_file
, "\n");
2326 error_at_line (&s
->u
.s
.line
,
2327 "structure alias is not a structure");
2333 /* Declare the marker procedure only once. */
2334 oprintf (header_file
, "extern void gt_pch_p_");
2335 output_mangled_typename (header_file
, s
);
2336 oprintf (header_file
,
2337 "\n (void *, void *, gt_pointer_operator, void *);\n");
2339 if (s
->kind
== TYPE_LANG_STRUCT
)
2342 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2343 write_local_func_for_structure (s
, ss
, NULL
);
2346 write_local_func_for_structure (s
, s
, NULL
);
2349 for (s
= param_structs
; s
; s
= s
->next
)
2350 if (s
->gc_used
== GC_POINTED_TO
)
2352 type_p
* param
= s
->u
.param_struct
.param
;
2353 type_p stru
= s
->u
.param_struct
.stru
;
2355 /* Declare the marker procedure. */
2356 oprintf (header_file
, "extern void gt_pch_p_");
2357 output_mangled_typename (header_file
, s
);
2358 oprintf (header_file
,
2359 "\n (void *, void *, gt_pointer_operator, void *);\n");
2361 if (stru
->u
.s
.line
.file
== NULL
)
2363 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2368 if (stru
->kind
== TYPE_LANG_STRUCT
)
2371 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2372 write_local_func_for_structure (s
, ss
, param
);
2375 write_local_func_for_structure (s
, stru
, param
);
2379 /* Write out the 'enum' definition for gt_types_enum. */
2382 write_enum_defn (type_p structures
, type_p param_structs
)
2386 oprintf (header_file
, "\n/* Enumeration of types known. */\n");
2387 oprintf (header_file
, "enum gt_types_enum {\n");
2388 for (s
= structures
; s
; s
= s
->next
)
2389 if (s
->gc_used
== GC_POINTED_TO
2390 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2392 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2393 && s
->u
.s
.line
.file
== NULL
)
2396 oprintf (header_file
, " gt_ggc_e_");
2397 output_mangled_typename (header_file
, s
);
2398 oprintf (header_file
, ", \n");
2400 for (s
= param_structs
; s
; s
= s
->next
)
2401 if (s
->gc_used
== GC_POINTED_TO
)
2403 oprintf (header_file
, " gt_e_");
2404 output_mangled_typename (header_file
, s
);
2405 oprintf (header_file
, ", \n");
2407 oprintf (header_file
, " gt_types_enum_last\n");
2408 oprintf (header_file
, "};\n");
2411 /* Might T contain any non-pointer elements? */
2414 contains_scalar_p (type_p t
)
2422 return contains_scalar_p (t
->u
.a
.p
);
2424 /* Could also check for structures that have no non-pointer
2425 fields, but there aren't enough of those to worry about. */
2430 /* Mangle FN and print it to F. */
2433 put_mangled_filename (outf_p f
, const char *fn
)
2435 const char *name
= get_output_file_name (fn
);
2436 for (; *name
!= 0; name
++)
2437 if (ISALNUM (*name
))
2438 oprintf (f
, "%c", *name
);
2440 oprintf (f
, "%c", '_');
2443 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2444 LASTNAME, and NAME are all strings to insert in various places in
2445 the resulting code. */
2448 finish_root_table (struct flist
*flp
, const char *pfx
, const char *lastname
,
2449 const char *tname
, const char *name
)
2453 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2454 if (fli2
->started_p
)
2456 oprintf (fli2
->f
, " %s\n", lastname
);
2457 oprintf (fli2
->f
, "};\n\n");
2460 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2461 if (fli2
->started_p
)
2463 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2466 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2469 oprintf (base_files
[fnum
],
2470 "extern const struct %s gt_%s_",
2472 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2473 oprintf (base_files
[fnum
], "[];\n");
2479 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2480 oprintf (base_files
[fnum
],
2481 "const struct %s * const %s[] = {\n",
2486 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2487 if (fli2
->started_p
)
2489 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2492 fli2
->started_p
= 0;
2494 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2497 oprintf (base_files
[fnum
], " gt_%s_", pfx
);
2498 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2499 oprintf (base_files
[fnum
], ",\n");
2505 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2507 oprintf (base_files
[fnum
], " NULL\n");
2508 oprintf (base_files
[fnum
], "};\n");
2513 /* Write out to F the table entry and any marker routines needed to
2514 mark NAME as TYPE. The original variable is V, at LINE.
2515 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2516 is nonzero iff we are building the root table for hash table caches. */
2519 write_root (outf_p f
, pair_p v
, type_p type
, const char *name
, int has_length
,
2520 struct fileloc
*line
, const char *if_marked
)
2527 for (fld
= type
->u
.s
.fields
; fld
; fld
= fld
->next
)
2530 const char *desc
= NULL
;
2533 for (o
= fld
->opt
; o
; o
= o
->next
)
2534 if (strcmp (o
->name
, "skip") == 0)
2536 else if (strcmp (o
->name
, "desc") == 0)
2537 desc
= (const char *)o
->info
;
2539 error_at_line (line
,
2540 "field `%s' of global `%s' has unknown option `%s'",
2541 fld
->name
, name
, o
->name
);
2545 else if (desc
&& fld
->type
->kind
== TYPE_UNION
)
2547 pair_p validf
= NULL
;
2550 for (ufld
= fld
->type
->u
.s
.fields
; ufld
; ufld
= ufld
->next
)
2552 const char *tag
= NULL
;
2555 for (oo
= ufld
->opt
; oo
; oo
= oo
->next
)
2556 if (strcmp (oo
->name
, "tag") == 0)
2557 tag
= (const char *)oo
->info
;
2558 if (tag
== NULL
|| strcmp (tag
, desc
) != 0)
2561 error_at_line (line
,
2562 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2563 name
, fld
->name
, validf
->name
,
2564 name
, fld
->name
, ufld
->name
,
2571 newname
= xasprintf ("%s.%s.%s",
2572 name
, fld
->name
, validf
->name
);
2573 write_root (f
, v
, validf
->type
, newname
, 0, line
,
2579 error_at_line (line
,
2580 "global `%s.%s' has `desc' option but is not union",
2585 newname
= xasprintf ("%s.%s", name
, fld
->name
);
2586 write_root (f
, v
, fld
->type
, newname
, 0, line
, if_marked
);
2596 newname
= xasprintf ("%s[0]", name
);
2597 write_root (f
, v
, type
->u
.a
.p
, newname
, has_length
, line
, if_marked
);
2606 oprintf (f
, " {\n");
2607 oprintf (f
, " &%s,\n", name
);
2610 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2612 oprintf (f
, " * (%s)", ap
->u
.a
.len
);
2613 else if (ap
== v
->type
)
2614 oprintf (f
, " * ARRAY_SIZE (%s)", v
->name
);
2616 oprintf (f
, " sizeof (%s", v
->name
);
2617 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2619 oprintf (f
, "),\n");
2623 if (! has_length
&& UNION_OR_STRUCT_P (tp
))
2625 oprintf (f
, " >_ggc_mx_%s,\n", tp
->u
.s
.tag
);
2626 oprintf (f
, " >_pch_nx_%s", tp
->u
.s
.tag
);
2628 else if (! has_length
&& tp
->kind
== TYPE_PARAM_STRUCT
)
2630 oprintf (f
, " >_ggc_m_");
2631 output_mangled_typename (f
, tp
);
2632 oprintf (f
, ",\n >_pch_n_");
2633 output_mangled_typename (f
, tp
);
2636 && (tp
->kind
== TYPE_POINTER
|| UNION_OR_STRUCT_P (tp
)))
2638 oprintf (f
, " >_ggc_ma_%s,\n", name
);
2639 oprintf (f
, " >_pch_na_%s", name
);
2643 error_at_line (line
,
2644 "global `%s' is pointer to unimplemented type",
2648 oprintf (f
, ",\n &%s", if_marked
);
2649 oprintf (f
, "\n },\n");
2655 oprintf (f
, " {\n");
2656 oprintf (f
, " &%s,\n", name
);
2657 oprintf (f
, " 1, \n");
2658 oprintf (f
, " sizeof (%s),\n", v
->name
);
2659 oprintf (f
, " >_ggc_m_S,\n");
2660 oprintf (f
, " (gt_pointer_walker) >_pch_n_S\n");
2661 oprintf (f
, " },\n");
2669 error_at_line (line
,
2670 "global `%s' is unimplemented type",
2675 /* This generates a routine to walk an array. */
2678 write_array (outf_p f
, pair_p v
, const struct write_types_data
*wtd
)
2680 struct walk_type_data d
;
2683 memset (&d
, 0, sizeof (d
));
2689 d
.bitmap
= get_base_file_bitmap (v
->line
.file
);
2692 d
.prev_val
[3] = prevval3
= xasprintf ("&%s", v
->name
);
2694 if (wtd
->param_prefix
)
2696 oprintf (f
, "static void gt_%sa_%s\n", wtd
->param_prefix
, v
->name
);
2698 " (void *, void *, gt_pointer_operator, void *);\n");
2699 oprintf (f
, "static void gt_%sa_%s (void *this_obj ATTRIBUTE_UNUSED,\n",
2700 wtd
->param_prefix
, v
->name
);
2701 oprintf (d
.of
, " void *x_p ATTRIBUTE_UNUSED,\n");
2702 oprintf (d
.of
, " gt_pointer_operator op ATTRIBUTE_UNUSED,\n");
2703 oprintf (d
.of
, " void *cookie ATTRIBUTE_UNUSED)\n");
2704 oprintf (d
.of
, "{\n");
2705 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2706 d
.process_field
= write_types_local_process_field
;
2707 walk_type (v
->type
, &d
);
2708 oprintf (f
, "}\n\n");
2712 oprintf (f
, "static void gt_%sa_%s (void *);\n",
2713 wtd
->prefix
, v
->name
);
2714 oprintf (f
, "static void\ngt_%sa_%s (void *x_p ATTRIBUTE_UNUSED)\n",
2715 wtd
->prefix
, v
->name
);
2717 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2718 d
.process_field
= write_types_process_field
;
2719 walk_type (v
->type
, &d
);
2721 oprintf (f
, "}\n\n");
2724 /* Output a table describing the locations and types of VARIABLES. */
2727 write_roots (pair_p variables
)
2730 struct flist
*flp
= NULL
;
2732 for (v
= variables
; v
; v
= v
->next
)
2734 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2736 const char *length
= NULL
;
2737 int deletable_p
= 0;
2740 for (o
= v
->opt
; o
; o
= o
->next
)
2741 if (strcmp (o
->name
, "length") == 0)
2742 length
= (const char *)o
->info
;
2743 else if (strcmp (o
->name
, "deletable") == 0)
2745 else if (strcmp (o
->name
, "param_is") == 0)
2747 else if (strncmp (o
->name
, "param", 5) == 0
2748 && ISDIGIT (o
->name
[5])
2749 && strcmp (o
->name
+ 6, "_is") == 0)
2751 else if (strcmp (o
->name
, "if_marked") == 0)
2754 error_at_line (&v
->line
,
2755 "global `%s' has unknown option `%s'",
2758 for (fli
= flp
; fli
; fli
= fli
->next
)
2763 fli
= xmalloc (sizeof (*fli
));
2767 fli
->name
= v
->line
.file
;
2770 oprintf (f
, "\n/* GC roots. */\n\n");
2775 && v
->type
->kind
== TYPE_POINTER
2776 && (v
->type
->u
.p
->kind
== TYPE_POINTER
2777 || v
->type
->u
.p
->kind
== TYPE_STRUCT
))
2779 write_array (f
, v
, &ggc_wtd
);
2780 write_array (f
, v
, &pch_wtd
);
2784 for (v
= variables
; v
; v
= v
->next
)
2786 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2792 for (o
= v
->opt
; o
; o
= o
->next
)
2793 if (strcmp (o
->name
, "length") == 0)
2795 else if (strcmp (o
->name
, "deletable") == 0
2796 || strcmp (o
->name
, "if_marked") == 0)
2802 for (fli
= flp
; fli
; fli
= fli
->next
)
2805 if (! fli
->started_p
)
2809 oprintf (f
, "const struct ggc_root_tab gt_ggc_r_");
2810 put_mangled_filename (f
, v
->line
.file
);
2811 oprintf (f
, "[] = {\n");
2814 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2817 finish_root_table (flp
, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2820 for (v
= variables
; v
; v
= v
->next
)
2822 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2827 for (o
= v
->opt
; o
; o
= o
->next
)
2828 if (strcmp (o
->name
, "deletable") == 0)
2830 else if (strcmp (o
->name
, "if_marked") == 0)
2836 for (fli
= flp
; fli
; fli
= fli
->next
)
2839 if (! fli
->started_p
)
2843 oprintf (f
, "const struct ggc_root_tab gt_ggc_rd_");
2844 put_mangled_filename (f
, v
->line
.file
);
2845 oprintf (f
, "[] = {\n");
2848 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2852 finish_root_table (flp
, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2853 "gt_ggc_deletable_rtab");
2855 for (v
= variables
; v
; v
= v
->next
)
2857 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2859 const char *if_marked
= NULL
;
2863 for (o
= v
->opt
; o
; o
= o
->next
)
2864 if (strcmp (o
->name
, "length") == 0)
2866 else if (strcmp (o
->name
, "if_marked") == 0)
2867 if_marked
= (const char *) o
->info
;
2869 if (if_marked
== NULL
)
2872 if (v
->type
->kind
!= TYPE_POINTER
2873 || v
->type
->u
.p
->kind
!= TYPE_PARAM_STRUCT
2874 || v
->type
->u
.p
->u
.param_struct
.stru
!= find_structure ("htab", 0))
2876 error_at_line (&v
->line
, "if_marked option used but not hash table");
2880 for (fli
= flp
; fli
; fli
= fli
->next
)
2883 if (! fli
->started_p
)
2887 oprintf (f
, "const struct ggc_cache_tab gt_ggc_rc_");
2888 put_mangled_filename (f
, v
->line
.file
);
2889 oprintf (f
, "[] = {\n");
2892 write_root (f
, v
, v
->type
->u
.p
->u
.param_struct
.param
[0],
2893 v
->name
, length_p
, &v
->line
, if_marked
);
2896 finish_root_table (flp
, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2897 "gt_ggc_cache_rtab");
2899 for (v
= variables
; v
; v
= v
->next
)
2901 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2904 int if_marked_p
= 0;
2907 for (o
= v
->opt
; o
; o
= o
->next
)
2908 if (strcmp (o
->name
, "length") == 0)
2910 else if (strcmp (o
->name
, "if_marked") == 0)
2916 for (fli
= flp
; fli
; fli
= fli
->next
)
2919 if (! fli
->started_p
)
2923 oprintf (f
, "const struct ggc_root_tab gt_pch_rc_");
2924 put_mangled_filename (f
, v
->line
.file
);
2925 oprintf (f
, "[] = {\n");
2928 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2931 finish_root_table (flp
, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2932 "gt_pch_cache_rtab");
2934 for (v
= variables
; v
; v
= v
->next
)
2936 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2941 for (o
= v
->opt
; o
; o
= o
->next
)
2942 if (strcmp (o
->name
, "deletable") == 0
2943 || strcmp (o
->name
, "if_marked") == 0)
2949 if (! contains_scalar_p (v
->type
))
2952 for (fli
= flp
; fli
; fli
= fli
->next
)
2955 if (! fli
->started_p
)
2959 oprintf (f
, "const struct ggc_root_tab gt_pch_rs_");
2960 put_mangled_filename (f
, v
->line
.file
);
2961 oprintf (f
, "[] = {\n");
2964 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2968 finish_root_table (flp
, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2969 "gt_pch_scalar_rtab");
2973 extern int main (int argc
, char **argv
);
2975 main(int argc ATTRIBUTE_UNUSED
, char **argv ATTRIBUTE_UNUSED
)
2978 static struct fileloc pos
= { __FILE__
, __LINE__
};
2983 srcdir_len
= strlen (srcdir
);
2985 do_scalar_typedef ("CUMULATIVE_ARGS", &pos
);
2986 do_scalar_typedef ("REAL_VALUE_TYPE", &pos
);
2987 do_scalar_typedef ("uint8", &pos
);
2988 do_scalar_typedef ("jword", &pos
);
2989 do_scalar_typedef ("JCF_u2", &pos
);
2990 do_scalar_typedef ("void", &pos
);
2992 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos
)), &pos
);
2994 do_typedef ("HARD_REG_SET", create_array (
2995 create_scalar_type ("unsigned long", strlen ("unsigned long")),
2998 for (i
= 0; i
< NUM_GT_FILES
; i
++)
3001 /* Omit if already seen. */
3002 for (j
= 0; j
< i
; j
++)
3004 if (!strcmp (all_files
[i
], all_files
[j
]))
3011 parse_file (all_files
[i
]);
3017 set_gc_used (variables
);
3020 write_enum_defn (structures
, param_structs
);
3021 write_types (structures
, param_structs
, &ggc_wtd
);
3022 write_types (structures
, param_structs
, &pch_wtd
);
3023 write_local (structures
, param_structs
);
3024 write_roots (variables
);
3026 close_output_files ();
3028 return (hit_error
!= 0);