1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
23 #include "coretypes.h"
29 /* Nonzero iff an error has occurred. */
30 static int hit_error
= 0;
32 static void gen_rtx_next (void);
33 static void write_rtx_next (void);
34 static void open_base_files (void);
35 static void close_output_files (void);
37 /* Report an error at POS, printing MSG. */
40 error_at_line (struct fileloc
*pos
, const char *msg
, ...)
46 fprintf (stderr
, "%s:%d: ", pos
->file
, pos
->line
);
47 vfprintf (stderr
, msg
, ap
);
54 /* vasprintf, but produces fatal message on out-of-memory. */
56 xvasprintf (char **result
, const char *format
, va_list args
)
58 int ret
= vasprintf (result
, format
, args
);
59 if (*result
== NULL
|| ret
< 0)
61 fputs ("gengtype: out of memory", stderr
);
67 /* Wrapper for xvasprintf. */
69 xasprintf (const char *format
, ...)
74 va_start (ap
, format
);
75 xvasprintf (&result
, format
, ap
);
80 /* The one and only TYPE_STRING. */
82 struct type string_type
= {
83 TYPE_STRING
, NULL
, NULL
, GC_USED
, {0}
86 /* Lists of various things. */
88 static pair_p typedefs
;
89 static type_p structures
;
90 static type_p param_structs
;
91 static pair_p variables
;
93 static void do_scalar_typedef (const char *, struct fileloc
*);
94 static type_p find_param_structure
95 (type_p t
, type_p param
[NUM_PARAM
]);
96 static type_p
adjust_field_tree_exp (type_p t
, options_p opt
);
97 static type_p
adjust_field_rtx_def (type_p t
, options_p opt
);
99 /* Define S as a typedef to T at POS. */
102 do_typedef (const char *s
, type_p t
, struct fileloc
*pos
)
106 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
107 if (strcmp (p
->name
, s
) == 0)
111 error_at_line (pos
, "type `%s' previously defined", s
);
112 error_at_line (&p
->line
, "previously defined here");
117 p
= XNEW (struct pair
);
125 /* Define S as a typename of a scalar. */
128 do_scalar_typedef (const char *s
, struct fileloc
*pos
)
130 do_typedef (s
, create_scalar_type (s
, strlen (s
)), pos
);
133 /* Return the type previously defined for S. Use POS to report errors. */
136 resolve_typedef (const char *s
, struct fileloc
*pos
)
139 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
140 if (strcmp (p
->name
, s
) == 0)
142 error_at_line (pos
, "unidentified type `%s'", s
);
143 return create_scalar_type ("char", 4);
146 /* Create and return a new structure with tag NAME (or a union iff
147 ISUNION is nonzero), at POS with fields FIELDS and options O. */
150 new_structure (const char *name
, int isunion
, struct fileloc
*pos
,
151 pair_p fields
, options_p o
)
155 lang_bitmap bitmap
= get_base_file_bitmap (pos
->file
);
157 for (si
= structures
; si
!= NULL
; si
= si
->next
)
158 if (strcmp (name
, si
->u
.s
.tag
) == 0
159 && UNION_P (si
) == isunion
)
162 if (si
->kind
== TYPE_LANG_STRUCT
)
166 for (si
= ls
->u
.s
.lang_struct
; si
!= NULL
; si
= si
->next
)
167 if (si
->u
.s
.bitmap
== bitmap
)
170 else if (si
->u
.s
.line
.file
!= NULL
&& si
->u
.s
.bitmap
!= bitmap
)
173 si
= XCNEW (struct type
);
174 memcpy (si
, ls
, sizeof (struct type
));
175 ls
->kind
= TYPE_LANG_STRUCT
;
176 ls
->u
.s
.lang_struct
= si
;
177 ls
->u
.s
.fields
= NULL
;
179 si
->pointer_to
= NULL
;
180 si
->u
.s
.lang_struct
= ls
;
185 if (ls
!= NULL
&& s
== NULL
)
187 s
= XCNEW (struct type
);
188 s
->next
= ls
->u
.s
.lang_struct
;
189 ls
->u
.s
.lang_struct
= s
;
190 s
->u
.s
.lang_struct
= ls
;
197 s
= XCNEW (struct type
);
198 s
->next
= structures
;
202 if (s
->u
.s
.line
.file
!= NULL
203 || (s
->u
.s
.lang_struct
&& (s
->u
.s
.lang_struct
->u
.s
.bitmap
& bitmap
)))
205 error_at_line (pos
, "duplicate structure definition");
206 error_at_line (&s
->u
.s
.line
, "previous definition here");
209 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
212 s
->u
.s
.fields
= fields
;
214 s
->u
.s
.bitmap
= bitmap
;
215 if (s
->u
.s
.lang_struct
)
216 s
->u
.s
.lang_struct
->u
.s
.bitmap
|= bitmap
;
221 /* Return the previously-defined structure with tag NAME (or a union
222 iff ISUNION is nonzero), or a new empty structure or union if none
223 was defined previously. */
226 find_structure (const char *name
, int isunion
)
230 for (s
= structures
; s
!= NULL
; s
= s
->next
)
231 if (strcmp (name
, s
->u
.s
.tag
) == 0
232 && UNION_P (s
) == isunion
)
235 s
= XCNEW (struct type
);
236 s
->next
= structures
;
238 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
244 /* Return the previously-defined parameterized structure for structure
245 T and parameters PARAM, or a new parameterized empty structure or
246 union if none was defined previously. */
249 find_param_structure (type_p t
, type_p param
[NUM_PARAM
])
253 for (res
= param_structs
; res
; res
= res
->next
)
254 if (res
->u
.param_struct
.stru
== t
255 && memcmp (res
->u
.param_struct
.param
, param
,
256 sizeof (type_p
) * NUM_PARAM
) == 0)
260 res
= XCNEW (struct type
);
261 res
->kind
= TYPE_PARAM_STRUCT
;
262 res
->next
= param_structs
;
264 res
->u
.param_struct
.stru
= t
;
265 memcpy (res
->u
.param_struct
.param
, param
, sizeof (type_p
) * NUM_PARAM
);
270 /* Return a scalar type with name NAME. */
273 create_scalar_type (const char *name
, size_t name_len
)
275 type_p r
= XCNEW (struct type
);
276 r
->kind
= TYPE_SCALAR
;
277 r
->u
.sc
= (char *) xmemdup (name
, name_len
, name_len
+ 1);
281 /* Return a pointer to T. */
284 create_pointer (type_p t
)
288 type_p r
= XCNEW (struct type
);
289 r
->kind
= TYPE_POINTER
;
293 return t
->pointer_to
;
296 /* Return an array of length LEN. */
299 create_array (type_p t
, const char *len
)
303 v
= XCNEW (struct type
);
304 v
->kind
= TYPE_ARRAY
;
310 /* Return an options structure with name NAME and info INFO. NEXT is the
311 next option in the chain. */
314 create_option (options_p next
, const char *name
, const void *info
)
316 options_p o
= XNEW (struct options
);
319 o
->info
= (const char*) info
;
323 /* Add a variable named S of type T with options O defined at POS,
327 note_variable (const char *s
, type_p t
, options_p o
, struct fileloc
*pos
)
330 n
= XNEW (struct pair
);
339 /* Create a fake field with the given type and name. NEXT is the next
340 field in the chain. */
343 create_field (pair_p next
, type_p type
, const char *name
)
347 field
= XNEW (struct pair
);
352 field
->line
.file
= __FILE__
;
353 field
->line
.line
= __LINE__
;
357 /* Like create_field, but the field is only valid when condition COND
361 create_optional_field (pair_p next
, type_p type
, const char *name
,
365 pair_p union_fields
, field
;
368 /* Create a fake union type with a single nameless field of type TYPE.
369 The field has a tag of "1". This allows us to make the presence
370 of a field of type TYPE depend on some boolean "desc" being true. */
371 union_fields
= create_field (NULL
, type
, "");
372 union_fields
->opt
= create_option (union_fields
->opt
, "dot", "");
373 union_fields
->opt
= create_option (union_fields
->opt
, "tag", "1");
374 union_type
= new_structure (xasprintf ("%s_%d", "fake_union", id
++), 1,
375 &lexer_line
, union_fields
, NULL
);
377 /* Create the field and give it the new fake union type. Add a "desc"
378 tag that specifies the condition under which the field is valid. */
379 field
= create_field (next
, union_type
, name
);
380 field
->opt
= create_option (field
->opt
, "desc", cond
);
384 /* We don't care how long a CONST_DOUBLE is. */
385 #define CONST_DOUBLE_FORMAT "ww"
386 /* We don't want to see codes that are only for generator files. */
387 #undef GENERATOR_FILE
390 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
396 static const char * const rtx_name
[NUM_RTX_CODE
] = {
397 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
402 static const char * const rtx_format
[NUM_RTX_CODE
] = {
403 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
408 static int rtx_next_new
[NUM_RTX_CODE
];
410 /* We also need codes and names for insn notes (not register notes).
411 Note that we do *not* bias the note values here. */
413 #define DEF_INSN_NOTE(NAME) NAME,
414 #include "insn-notes.def"
420 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
421 default field for line number notes. */
422 static const char *const note_insn_name
[NOTE_INSN_MAX
+1] = {
423 #define DEF_INSN_NOTE(NAME) #NAME,
424 #include "insn-notes.def"
428 #undef CONST_DOUBLE_FORMAT
429 #define GENERATOR_FILE
431 /* Generate the contents of the rtx_next array. This really doesn't belong
432 in gengtype at all, but it's needed for adjust_field_rtx_def. */
438 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
442 rtx_next_new
[i
] = -1;
443 if (strncmp (rtx_format
[i
], "iuu", 3) == 0)
445 else if (i
== COND_EXEC
|| i
== SET
|| i
== EXPR_LIST
|| i
== INSN_LIST
)
448 for (k
= strlen (rtx_format
[i
]) - 1; k
>= 0; k
--)
449 if (rtx_format
[i
][k
] == 'e' || rtx_format
[i
][k
] == 'u')
454 /* Write out the contents of the rtx_next array. */
456 write_rtx_next (void)
458 outf_p f
= get_output_file_with_visibility (NULL
);
461 oprintf (f
, "\n/* Used to implement the RTX_NEXT macro. */\n");
462 oprintf (f
, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
463 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
464 if (rtx_next_new
[i
] == -1)
465 oprintf (f
, " 0,\n");
468 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
473 /* Handle `special("rtx_def")'. This is a special case for field
474 `fld' of struct rtx_def, which is an array of unions whose values
475 are based in a complex way on the type of RTL. */
478 adjust_field_rtx_def (type_p t
, options_p
ARG_UNUSED (opt
))
483 type_p rtx_tp
, rtvec_tp
, tree_tp
, mem_attrs_tp
, note_union_tp
, scalar_tp
;
484 type_p bitmap_tp
, basic_block_tp
, reg_attrs_tp
, constant_tp
, symbol_union_tp
;
486 if (t
->kind
!= TYPE_UNION
)
488 error_at_line (&lexer_line
,
489 "special `rtx_def' must be applied to a union");
493 nodot
= create_option (NULL
, "dot", "");
495 rtx_tp
= create_pointer (find_structure ("rtx_def", 0));
496 rtvec_tp
= create_pointer (find_structure ("rtvec_def", 0));
497 tree_tp
= create_pointer (find_structure ("tree_node", 1));
498 mem_attrs_tp
= create_pointer (find_structure ("mem_attrs", 0));
499 reg_attrs_tp
= create_pointer (find_structure ("reg_attrs", 0));
500 bitmap_tp
= create_pointer (find_structure ("bitmap_element_def", 0));
501 basic_block_tp
= create_pointer (find_structure ("basic_block_def", 0));
502 constant_tp
= create_pointer (find_structure ("constant_descriptor_rtx", 0));
503 scalar_tp
= create_scalar_type ("rtunion scalar", 14);
506 pair_p note_flds
= NULL
;
509 for (c
= 0; c
<= NOTE_INSN_MAX
; c
++)
514 note_flds
= create_field (note_flds
, &string_type
, "rt_str");
517 case NOTE_INSN_BLOCK_BEG
:
518 case NOTE_INSN_BLOCK_END
:
519 note_flds
= create_field (note_flds
, tree_tp
, "rt_tree");
522 case NOTE_INSN_VAR_LOCATION
:
523 note_flds
= create_field (note_flds
, rtx_tp
, "rt_rtx");
527 note_flds
= create_field (note_flds
, scalar_tp
, "rt_int");
530 /* NOTE_INSN_MAX is used as the default field for line
532 if (c
== NOTE_INSN_MAX
)
533 note_flds
->opt
= create_option (nodot
, "default", "");
535 note_flds
->opt
= create_option (nodot
, "tag", note_insn_name
[c
]);
537 note_union_tp
= new_structure ("rtx_def_note_subunion", 1,
538 &lexer_line
, note_flds
, NULL
);
540 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */
544 sym_flds
= create_field (NULL
, tree_tp
, "rt_tree");
545 sym_flds
->opt
= create_option (nodot
, "default", "");
547 sym_flds
= create_field (sym_flds
, constant_tp
, "rt_constant");
548 sym_flds
->opt
= create_option (nodot
, "tag", "1");
550 symbol_union_tp
= new_structure ("rtx_def_symbol_subunion", 1,
551 &lexer_line
, sym_flds
, NULL
);
553 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
555 pair_p subfields
= NULL
;
556 size_t aindex
, nmindex
;
561 for (aindex
= 0; aindex
< strlen (rtx_format
[i
]); aindex
++)
566 switch (rtx_format
[i
][aindex
])
577 if (i
== MEM
&& aindex
== 1)
578 t
= mem_attrs_tp
, subname
= "rt_mem";
579 else if (i
== JUMP_INSN
&& aindex
== 9)
580 t
= rtx_tp
, subname
= "rt_rtx";
581 else if (i
== CODE_LABEL
&& aindex
== 4)
582 t
= scalar_tp
, subname
= "rt_int";
583 else if (i
== CODE_LABEL
&& aindex
== 5)
584 t
= rtx_tp
, subname
= "rt_rtx";
585 else if (i
== LABEL_REF
586 && (aindex
== 1 || aindex
== 2))
587 t
= rtx_tp
, subname
= "rt_rtx";
588 else if (i
== NOTE
&& aindex
== 4)
589 t
= note_union_tp
, subname
= "";
590 else if (i
== NOTE
&& aindex
>= 7)
591 t
= scalar_tp
, subname
= "rt_int";
592 else if (i
== ADDR_DIFF_VEC
&& aindex
== 4)
593 t
= scalar_tp
, subname
= "rt_int";
594 else if (i
== VALUE
&& aindex
== 0)
595 t
= scalar_tp
, subname
= "rt_int";
596 else if (i
== REG
&& aindex
== 1)
597 t
= scalar_tp
, subname
= "rt_int";
598 else if (i
== REG
&& aindex
== 2)
599 t
= reg_attrs_tp
, subname
= "rt_reg";
600 else if (i
== SCRATCH
&& aindex
== 0)
601 t
= scalar_tp
, subname
= "rt_int";
602 else if (i
== SYMBOL_REF
&& aindex
== 1)
603 t
= scalar_tp
, subname
= "rt_int";
604 else if (i
== SYMBOL_REF
&& aindex
== 2)
605 t
= symbol_union_tp
, subname
= "";
606 else if (i
== BARRIER
&& aindex
>= 3)
607 t
= scalar_tp
, subname
= "rt_int";
610 error_at_line (&lexer_line
,
611 "rtx type `%s' has `0' in position %lu, can't handle",
612 rtx_name
[i
], (unsigned long) aindex
);
634 subname
= "rt_rtvec";
653 error_at_line (&lexer_line
,
654 "rtx type `%s' has `%c' in position %lu, can't handle",
655 rtx_name
[i
], rtx_format
[i
][aindex
],
656 (unsigned long)aindex
);
662 subfields
= create_field (subfields
, t
,
663 xasprintf (".fld[%lu].%s",
664 (unsigned long) aindex
,
666 subfields
->opt
= nodot
;
667 if (t
== note_union_tp
)
668 subfields
->opt
= create_option (subfields
->opt
, "desc",
669 "NOTE_LINE_NUMBER (&%0)");
670 if (t
== symbol_union_tp
)
671 subfields
->opt
= create_option (subfields
->opt
, "desc",
672 "CONSTANT_POOL_ADDRESS_P (&%0)");
677 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
678 type_p field_tp
= find_structure ("block_symbol", 0);
680 = create_optional_field (subfields
, field_tp
, "block_sym",
681 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
684 sname
= xasprintf ("rtx_def_%s", rtx_name
[i
]);
685 substruct
= new_structure (sname
, 0, &lexer_line
, subfields
, NULL
);
687 ftag
= xstrdup (rtx_name
[i
]);
688 for (nmindex
= 0; nmindex
< strlen (ftag
); nmindex
++)
689 ftag
[nmindex
] = TOUPPER (ftag
[nmindex
]);
691 flds
= create_field (flds
, substruct
, "");
692 flds
->opt
= create_option (nodot
, "tag", ftag
);
695 return new_structure ("rtx_def_subunion", 1, &lexer_line
, flds
, nodot
);
698 /* Handle `special("tree_exp")'. This is a special case for
699 field `operands' of struct tree_exp, which although it claims to contain
700 pointers to trees, actually sometimes contains pointers to RTL too.
701 Passed T, the old type of the field, and OPT its options. Returns
702 a new type for the field. */
705 adjust_field_tree_exp (type_p t
, options_p opt ATTRIBUTE_UNUSED
)
710 if (t
->kind
!= TYPE_ARRAY
)
712 error_at_line (&lexer_line
,
713 "special `tree_exp' must be applied to an array");
717 nodot
= create_option (NULL
, "dot", "");
719 flds
= create_field (NULL
, t
, "");
720 flds
->opt
= create_option (nodot
, "length",
721 "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))");
722 flds
->opt
= create_option (flds
->opt
, "default", "");
724 return new_structure ("tree_exp_subunion", 1, &lexer_line
, flds
, nodot
);
727 /* Perform any special processing on a type T, about to become the type
728 of a field. Return the appropriate type for the field.
730 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
731 - Similarly for arrays of pointer-to-char;
732 - Converts structures for which a parameter is provided to
734 - Handles "special" options.
738 adjust_field_type (type_p t
, options_p opt
)
741 const int pointer_p
= t
->kind
== TYPE_POINTER
;
742 type_p params
[NUM_PARAM
];
746 for (i
= 0; i
< NUM_PARAM
; i
++)
749 for (; opt
; opt
= opt
->next
)
750 if (strcmp (opt
->name
, "length") == 0)
752 else if (strcmp (opt
->name
, "param_is") == 0
753 || (strncmp (opt
->name
, "param", 5) == 0
754 && ISDIGIT (opt
->name
[5])
755 && strcmp (opt
->name
+ 6, "_is") == 0))
757 int num
= ISDIGIT (opt
->name
[5]) ? opt
->name
[5] - '0' : 0;
759 if (! UNION_OR_STRUCT_P (t
)
760 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
762 error_at_line (&lexer_line
,
763 "option `%s' may only be applied to structures or structure pointers",
769 if (params
[num
] != NULL
)
770 error_at_line (&lexer_line
, "duplicate `%s' option", opt
->name
);
771 if (! ISDIGIT (opt
->name
[5]))
772 params
[num
] = create_pointer ((type_p
) opt
->info
);
774 params
[num
] = (type_p
) opt
->info
;
776 else if (strcmp (opt
->name
, "special") == 0)
778 const char *special_name
= opt
->info
;
779 if (strcmp (special_name
, "tree_exp") == 0)
780 t
= adjust_field_tree_exp (t
, opt
);
781 else if (strcmp (special_name
, "rtx_def") == 0)
782 t
= adjust_field_rtx_def (t
, opt
);
784 error_at_line (&lexer_line
, "unknown special `%s'", special_name
);
793 realt
= find_param_structure (t
, params
);
794 t
= pointer_p
? create_pointer (realt
) : realt
;
799 && t
->u
.p
->kind
== TYPE_SCALAR
800 && (strcmp (t
->u
.p
->u
.sc
, "char") == 0
801 || strcmp (t
->u
.p
->u
.sc
, "unsigned char") == 0))
803 if (t
->kind
== TYPE_ARRAY
&& t
->u
.a
.p
->kind
== TYPE_POINTER
804 && t
->u
.a
.p
->u
.p
->kind
== TYPE_SCALAR
805 && (strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "char") == 0
806 || strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "unsigned char") == 0))
807 return create_array (&string_type
, t
->u
.a
.len
);
812 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
813 and information about the correspondence between token types and fields
814 in TYPEINFO. POS is used for error messages. */
817 note_yacc_type (options_p o
, pair_p fields
, pair_p typeinfo
,
823 for (p
= typeinfo
; p
; p
= p
->next
)
830 if (p
->type
== (type_p
) 1)
835 for (pp
= typeinfo
; pp
; pp
= pp
->next
)
836 if (pp
->type
!= (type_p
) 1
837 && strcmp (pp
->opt
->info
, p
->opt
->info
) == 0)
846 for (m
= fields
; m
; m
= m
->next
)
847 if (strcmp (m
->name
, p
->name
) == 0)
851 error_at_line (&p
->line
,
852 "couldn't match fieldname `%s'", p
->name
);
863 || p
->type
== (type_p
) 1)
869 do_typedef ("YYSTYPE", new_structure ("yy_union", 1, pos
, typeinfo
, o
), pos
);
872 static void process_gc_options (options_p
, enum gc_used_enum
,
873 int *, int *, int *, type_p
*);
874 static void set_gc_used_type (type_p
, enum gc_used_enum
, type_p
*);
875 static void set_gc_used (pair_p
);
877 /* Handle OPT for set_gc_used_type. */
880 process_gc_options (options_p opt
, enum gc_used_enum level
, int *maybe_undef
,
881 int *pass_param
, int *length
, type_p
*nested_ptr
)
884 for (o
= opt
; o
; o
= o
->next
)
885 if (strcmp (o
->name
, "ptr_alias") == 0 && level
== GC_POINTED_TO
)
886 set_gc_used_type ((type_p
) o
->info
, GC_POINTED_TO
, NULL
);
887 else if (strcmp (o
->name
, "maybe_undef") == 0)
889 else if (strcmp (o
->name
, "use_params") == 0)
891 else if (strcmp (o
->name
, "length") == 0)
893 else if (strcmp (o
->name
, "nested_ptr") == 0)
894 *nested_ptr
= ((const struct nested_ptr_data
*) o
->info
)->type
;
897 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
900 set_gc_used_type (type_p t
, enum gc_used_enum level
, type_p param
[NUM_PARAM
])
902 if (t
->gc_used
>= level
)
916 process_gc_options (t
->u
.s
.opt
, level
, &dummy
, &dummy
, &dummy
,
919 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
924 type_p nested_ptr
= NULL
;
925 process_gc_options (f
->opt
, level
, &maybe_undef
, &pass_param
,
926 &length
, &nested_ptr
);
928 if (nested_ptr
&& f
->type
->kind
== TYPE_POINTER
)
929 set_gc_used_type (nested_ptr
, GC_POINTED_TO
,
930 pass_param
? param
: NULL
);
931 else if (length
&& f
->type
->kind
== TYPE_POINTER
)
932 set_gc_used_type (f
->type
->u
.p
, GC_USED
, NULL
);
933 else if (maybe_undef
&& f
->type
->kind
== TYPE_POINTER
)
934 set_gc_used_type (f
->type
->u
.p
, GC_MAYBE_POINTED_TO
, NULL
);
935 else if (pass_param
&& f
->type
->kind
== TYPE_POINTER
&& param
)
936 set_gc_used_type (find_param_structure (f
->type
->u
.p
, param
),
937 GC_POINTED_TO
, NULL
);
939 set_gc_used_type (f
->type
, GC_USED
, pass_param
? param
: NULL
);
945 set_gc_used_type (t
->u
.p
, GC_POINTED_TO
, NULL
);
949 set_gc_used_type (t
->u
.a
.p
, GC_USED
, param
);
952 case TYPE_LANG_STRUCT
:
953 for (t
= t
->u
.s
.lang_struct
; t
; t
= t
->next
)
954 set_gc_used_type (t
, level
, param
);
957 case TYPE_PARAM_STRUCT
:
960 for (i
= 0; i
< NUM_PARAM
; i
++)
961 if (t
->u
.param_struct
.param
[i
] != 0)
962 set_gc_used_type (t
->u
.param_struct
.param
[i
], GC_USED
, NULL
);
964 if (t
->u
.param_struct
.stru
->gc_used
== GC_POINTED_TO
)
965 level
= GC_POINTED_TO
;
968 t
->u
.param_struct
.stru
->gc_used
= GC_UNUSED
;
969 set_gc_used_type (t
->u
.param_struct
.stru
, level
,
970 t
->u
.param_struct
.param
);
978 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
981 set_gc_used (pair_p variables
)
984 for (p
= variables
; p
; p
= p
->next
)
985 set_gc_used_type (p
->type
, GC_USED
, NULL
);
988 /* File mapping routines. For each input file, there is one output .c file
989 (but some output files have many input files), and there is one .h file
990 for the whole build. */
992 /* The list of output files. */
993 static outf_p output_files
;
995 /* The output header file that is included into pretty much every
997 static outf_p header_file
;
999 /* Number of files specified in gtfiles. */
1000 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1002 /* Number of files in the language files array. */
1003 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1005 /* Length of srcdir name. */
1006 static int srcdir_len
= 0;
1008 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1009 outf_p base_files
[NUM_BASE_FILES
];
1011 static outf_p
create_file (const char *, const char *);
1012 static const char * get_file_basename (const char *);
1014 /* Create and return an outf_p for a new file for NAME, to be called
1018 create_file (const char *name
, const char *oname
)
1020 static const char *const hdr
[] = {
1021 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
1023 "This file is part of GCC.\n",
1025 "GCC is free software; you can redistribute it and/or modify it under\n",
1026 "the terms of the GNU General Public License as published by the Free\n",
1027 "Software Foundation; either version 2, or (at your option) any later\n",
1030 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1031 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1032 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1033 "for more details.\n",
1035 "You should have received a copy of the GNU General Public License\n",
1036 "along with GCC; see the file COPYING. If not, write to the Free\n",
1037 "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1038 "02110-1301, USA. */\n",
1040 "/* This file is machine generated. Do not edit. */\n"
1045 f
= XCNEW (struct outf
);
1046 f
->next
= output_files
;
1050 oprintf (f
, "/* Type information for %s.\n", name
);
1051 for (i
= 0; i
< ARRAY_SIZE (hdr
); i
++)
1052 oprintf (f
, "%s", hdr
[i
]);
1056 /* Print, like fprintf, to O. */
1058 oprintf (outf_p o
, const char *format
, ...)
1064 va_start (ap
, format
);
1065 slength
= xvasprintf (&s
, format
, ap
);
1067 if (o
->bufused
+ slength
> o
->buflength
)
1069 size_t new_len
= o
->buflength
;
1074 } while (o
->bufused
+ slength
>= new_len
);
1075 o
->buf
= XRESIZEVEC (char, o
->buf
, new_len
);
1076 o
->buflength
= new_len
;
1078 memcpy (o
->buf
+ o
->bufused
, s
, slength
);
1079 o
->bufused
+= slength
;
1084 /* Open the global header file and the language-specific header files. */
1087 open_base_files (void)
1091 header_file
= create_file ("GCC", "gtype-desc.h");
1093 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1094 base_files
[i
] = create_file (lang_dir_names
[i
],
1095 xasprintf ("gtype-%s.h", lang_dir_names
[i
]));
1097 /* gtype-desc.c is a little special, so we create it here. */
1099 /* The order of files here matters very much. */
1100 static const char *const ifiles
[] = {
1101 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1102 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1103 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1104 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1105 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1106 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1107 "except.h", "output.h", NULL
1109 const char *const *ifp
;
1110 outf_p gtype_desc_c
;
1112 gtype_desc_c
= create_file ("GCC", "gtype-desc.c");
1113 for (ifp
= ifiles
; *ifp
; ifp
++)
1114 oprintf (gtype_desc_c
, "#include \"%s\"\n", *ifp
);
1118 /* Determine the pathname to F relative to $(srcdir). */
1121 get_file_basename (const char *f
)
1123 const char *basename
;
1126 basename
= strrchr (f
, '/');
1133 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1139 s1
= basename
- strlen (lang_dir_names
[i
]) - 1;
1140 s2
= lang_dir_names
[i
];
1143 if (l1
>= l2
&& IS_DIR_SEPARATOR (s1
[-1]) && !memcmp (s1
, s2
, l2
))
1146 if ((basename
- f
- 1) != srcdir_len
)
1147 fatal ("filename `%s' should be preceded by $srcdir", f
);
1155 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1156 INPUT_FILE is used by <lang>.
1158 This function should be written to assume that a file _is_ used
1159 if the situation is unclear. If it wrongly assumes a file _is_ used,
1160 a linker error will result. If it wrongly assumes a file _is not_ used,
1161 some GC roots may be missed, which is a much harder-to-debug problem. */
1164 get_base_file_bitmap (const char *input_file
)
1166 const char *basename
= get_file_basename (input_file
);
1167 const char *slashpos
= strchr (basename
, '/');
1172 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1173 it belongs to the corresponding language. The file may belong to other
1174 languages as well (which is checked for below). */
1179 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1180 if ((size_t)(slashpos
- basename
) == strlen (lang_dir_names
[i
])
1181 && memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0)
1183 /* It's in a language directory, set that language. */
1188 /* If it's in any config-lang.in, then set for the languages
1193 for (j
= 0; j
< NUM_LANG_FILES
; j
++)
1195 if (!strcmp(input_file
, lang_files
[j
]))
1197 for (k
= 0; k
< NUM_BASE_FILES
; k
++)
1199 if (!strcmp(lang_dir_names
[k
], langs_for_lang_files
[j
]))
1205 /* Otherwise, set all languages. */
1207 bitmap
= (1 << NUM_BASE_FILES
) - 1;
1212 /* An output file, suitable for definitions, that can see declarations
1213 made in INPUT_FILE and is linked into every language that uses
1217 get_output_file_with_visibility (const char *input_file
)
1221 const char *basename
;
1222 const char *for_name
;
1223 const char *output_name
;
1225 /* This can happen when we need a file with visibility on a
1226 structure that we've never seen. We have to just hope that it's
1227 globally visible. */
1228 if (input_file
== NULL
)
1229 input_file
= "system.h";
1231 /* Determine the output file name. */
1232 basename
= get_file_basename (input_file
);
1234 len
= strlen (basename
);
1235 if ((len
> 2 && memcmp (basename
+len
-2, ".c", 2) == 0)
1236 || (len
> 2 && memcmp (basename
+len
-2, ".y", 2) == 0)
1237 || (len
> 3 && memcmp (basename
+len
-3, ".in", 3) == 0))
1241 output_name
= s
= xasprintf ("gt-%s", basename
);
1242 for (; *s
!= '.'; s
++)
1243 if (! ISALNUM (*s
) && *s
!= '-')
1245 memcpy (s
, ".h", sizeof (".h"));
1246 for_name
= basename
;
1248 /* Some headers get used by more than one front-end; hence, it
1249 would be inappropriate to spew them out to a single gtype-<lang>.h
1250 (and gengtype doesn't know how to direct spewage into multiple
1251 gtype-<lang>.h headers at this time). Instead, we pair up these
1252 headers with source files (and their special purpose gt-*.h headers). */
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";
1257 else if (strncmp (basename
, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename
[2])
1258 && strcmp (basename
+ 3, "cp-tree.h") == 0)
1259 output_name
= "gt-cp-tree.h", for_name
= "cp/tree.c";
1260 else if (strncmp (basename
, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename
[2])
1261 && strcmp (basename
+ 3, "decl.h") == 0)
1262 output_name
= "gt-cp-decl.h", for_name
= "cp/decl.c";
1263 else if (strncmp (basename
, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename
[2])
1264 && strcmp (basename
+ 3, "name-lookup.h") == 0)
1265 output_name
= "gt-cp-name-lookup.h", for_name
= "cp/name-lookup.c";
1266 else if (strncmp (basename
, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename
[4])
1267 && strcmp (basename
+ 5, "objc-act.h") == 0)
1268 output_name
= "gt-objc-objc-act.h", for_name
= "objc/objc-act.c";
1273 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1274 if (memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0
1275 && basename
[strlen(lang_dir_names
[i
])] == '/')
1276 return base_files
[i
];
1278 output_name
= "gtype-desc.c";
1282 /* Look through to see if we've ever seen this output filename before. */
1283 for (r
= output_files
; r
; r
= r
->next
)
1284 if (strcmp (r
->name
, output_name
) == 0)
1287 /* If not, create it. */
1288 r
= create_file (for_name
, output_name
);
1293 /* The name of an output file, suitable for definitions, that can see
1294 declarations made in INPUT_FILE and is linked into every language
1295 that uses INPUT_FILE. */
1298 get_output_file_name (const char *input_file
)
1300 return get_output_file_with_visibility (input_file
)->name
;
1303 /* Copy the output to its final destination,
1304 but don't unnecessarily change modification times. */
1307 close_output_files (void)
1311 for (of
= output_files
; of
; of
= of
->next
)
1315 newfile
= fopen (of
->name
, "r");
1316 if (newfile
!= NULL
)
1321 for (i
= 0; i
< of
->bufused
; i
++)
1324 ch
= fgetc (newfile
);
1325 if (ch
== EOF
|| ch
!= (unsigned char) of
->buf
[i
])
1328 no_write_p
= i
== of
->bufused
&& fgetc (newfile
) == EOF
;
1335 newfile
= fopen (of
->name
, "w");
1336 if (newfile
== NULL
)
1338 perror ("opening output file");
1341 if (fwrite (of
->buf
, 1, of
->bufused
, newfile
) != of
->bufused
)
1343 perror ("writing output file");
1346 if (fclose (newfile
) != 0)
1348 perror ("closing output file");
1361 struct walk_type_data
;
1363 /* For scalars and strings, given the item in 'val'.
1364 For structures, given a pointer to the item in 'val'.
1365 For misc. pointers, given the item in 'val'.
1367 typedef void (*process_field_fn
)
1368 (type_p f
, const struct walk_type_data
*p
);
1369 typedef void (*func_name_fn
)
1370 (type_p s
, const struct walk_type_data
*p
);
1372 /* Parameters for write_types. */
1374 struct write_types_data
1377 const char *param_prefix
;
1378 const char *subfield_marker_routine
;
1379 const char *marker_routine
;
1380 const char *reorder_note_routine
;
1381 const char *comment
;
1384 static void output_escaped_param (struct walk_type_data
*d
,
1385 const char *, const char *);
1386 static void output_mangled_typename (outf_p
, type_p
);
1387 static void walk_type (type_p t
, struct walk_type_data
*d
);
1388 static void write_func_for_structure
1389 (type_p orig_s
, type_p s
, type_p
* param
,
1390 const struct write_types_data
*wtd
);
1391 static void write_types_process_field
1392 (type_p f
, const struct walk_type_data
*d
);
1393 static void write_types (type_p structures
,
1394 type_p param_structs
,
1395 const struct write_types_data
*wtd
);
1396 static void write_types_local_process_field
1397 (type_p f
, const struct walk_type_data
*d
);
1398 static void write_local_func_for_structure
1399 (type_p orig_s
, type_p s
, type_p
* param
);
1400 static void write_local (type_p structures
,
1401 type_p param_structs
);
1402 static void write_enum_defn (type_p structures
, type_p param_structs
);
1403 static int contains_scalar_p (type_p t
);
1404 static void put_mangled_filename (outf_p
, const char *);
1405 static void finish_root_table (struct flist
*flp
, const char *pfx
,
1406 const char *tname
, const char *lastname
,
1408 static void write_root (outf_p
, pair_p
, type_p
, const char *, int,
1409 struct fileloc
*, const char *);
1410 static void write_array (outf_p f
, pair_p v
,
1411 const struct write_types_data
*wtd
);
1412 static void write_roots (pair_p
);
1414 /* Parameters for walk_type. */
1416 struct walk_type_data
1418 process_field_fn process_field
;
1423 const char *prev_val
[4];
1426 struct fileloc
*line
;
1431 const char *reorder_fn
;
1433 bool fn_wants_lvalue
;
1436 /* Print a mangled name representing T to OF. */
1439 output_mangled_typename (outf_p of
, type_p t
)
1443 else switch (t
->kind
)
1447 output_mangled_typename (of
, t
->u
.p
);
1457 case TYPE_LANG_STRUCT
:
1458 oprintf (of
, "%lu%s", (unsigned long) strlen (t
->u
.s
.tag
), t
->u
.s
.tag
);
1460 case TYPE_PARAM_STRUCT
:
1463 for (i
= 0; i
< NUM_PARAM
; i
++)
1464 if (t
->u
.param_struct
.param
[i
] != NULL
)
1465 output_mangled_typename (of
, t
->u
.param_struct
.param
[i
]);
1466 output_mangled_typename (of
, t
->u
.param_struct
.stru
);
1474 /* Print PARAM to D->OF processing escapes. D->VAL references the
1475 current object, D->PREV_VAL the object containing the current
1476 object, ONAME is the name of the option and D->LINE is used to
1477 print error messages. */
1480 output_escaped_param (struct walk_type_data
*d
, const char *param
,
1485 for (p
= param
; *p
; p
++)
1487 oprintf (d
->of
, "%c", *p
);
1491 oprintf (d
->of
, "(%s)", d
->prev_val
[2]);
1494 oprintf (d
->of
, "(%s)", d
->prev_val
[0]);
1497 oprintf (d
->of
, "(%s)", d
->prev_val
[1]);
1501 const char *pp
= d
->val
+ strlen (d
->val
);
1502 while (pp
[-1] == ']')
1505 oprintf (d
->of
, "%s", pp
);
1509 error_at_line (d
->line
, "`%s' option contains bad escape %c%c",
1514 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1515 which is of type T. Write code to D->OF to constrain execution (at
1516 the point that D->PROCESS_FIELD is called) to the appropriate
1517 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1518 pointers to those objects. D->PREV_VAL lists the objects
1519 containing the current object, D->OPT is a list of options to
1520 apply, D->INDENT is the current indentation level, D->LINE is used
1521 to print error messages, D->BITMAP indicates which languages to
1522 print the structure for, and D->PARAM is the current parameter
1523 (from an enclosing param_is option). */
1526 walk_type (type_p t
, struct walk_type_data
*d
)
1528 const char *length
= NULL
;
1529 const char *desc
= NULL
;
1530 int maybe_undef_p
= 0;
1531 int use_param_num
= -1;
1532 int use_params_p
= 0;
1534 const struct nested_ptr_data
*nested_ptr_d
= NULL
;
1536 d
->needs_cast_p
= false;
1537 for (oo
= d
->opt
; oo
; oo
= oo
->next
)
1538 if (strcmp (oo
->name
, "length") == 0)
1540 else if (strcmp (oo
->name
, "maybe_undef") == 0)
1542 else if (strncmp (oo
->name
, "use_param", 9) == 0
1543 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1544 use_param_num
= oo
->name
[9] == '\0' ? 0 : oo
->name
[9] - '0';
1545 else if (strcmp (oo
->name
, "use_params") == 0)
1547 else if (strcmp (oo
->name
, "desc") == 0)
1549 else if (strcmp (oo
->name
, "nested_ptr") == 0)
1550 nested_ptr_d
= (const struct nested_ptr_data
*) oo
->info
;
1551 else if (strcmp (oo
->name
, "dot") == 0)
1553 else if (strcmp (oo
->name
, "tag") == 0)
1555 else if (strcmp (oo
->name
, "special") == 0)
1557 else if (strcmp (oo
->name
, "skip") == 0)
1559 else if (strcmp (oo
->name
, "default") == 0)
1561 else if (strcmp (oo
->name
, "descbits") == 0)
1563 else if (strcmp (oo
->name
, "param_is") == 0)
1565 else if (strncmp (oo
->name
, "param", 5) == 0
1566 && ISDIGIT (oo
->name
[5])
1567 && strcmp (oo
->name
+ 6, "_is") == 0)
1569 else if (strcmp (oo
->name
, "chain_next") == 0)
1571 else if (strcmp (oo
->name
, "chain_prev") == 0)
1573 else if (strcmp (oo
->name
, "reorder") == 0)
1576 error_at_line (d
->line
, "unknown option `%s'\n", oo
->name
);
1583 int pointer_p
= t
->kind
== TYPE_POINTER
;
1587 if (! UNION_OR_STRUCT_P (t
))
1588 error_at_line (d
->line
, "`use_params' option on unimplemented type");
1590 t
= find_param_structure (t
, d
->param
);
1592 t
= create_pointer (t
);
1595 if (use_param_num
!= -1)
1597 if (d
->param
!= NULL
&& d
->param
[use_param_num
] != NULL
)
1599 type_p nt
= d
->param
[use_param_num
];
1601 if (t
->kind
== TYPE_ARRAY
)
1602 nt
= create_array (nt
, t
->u
.a
.len
);
1603 else if (length
!= NULL
&& t
->kind
== TYPE_POINTER
)
1604 nt
= create_pointer (nt
);
1605 d
->needs_cast_p
= (t
->kind
!= TYPE_POINTER
1606 && (nt
->kind
== TYPE_POINTER
1607 || nt
->kind
== TYPE_STRING
));
1611 error_at_line (d
->line
, "no parameter defined for `%s'",
1616 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
1618 error_at_line (d
->line
,
1619 "field `%s' has invalid option `maybe_undef_p'\n",
1628 d
->process_field (t
, d
);
1634 && t
->u
.p
->u
.s
.line
.file
== NULL
)
1636 oprintf (d
->of
, "%*sgcc_assert (!%s);\n", d
->indent
, "", d
->val
);
1642 if (! UNION_OR_STRUCT_P (t
->u
.p
)
1643 && t
->u
.p
->kind
!= TYPE_PARAM_STRUCT
)
1645 error_at_line (d
->line
,
1646 "field `%s' is pointer to unimplemented type",
1653 const char *oldprevval2
= d
->prev_val
[2];
1655 if (! UNION_OR_STRUCT_P (nested_ptr_d
->type
))
1657 error_at_line (d
->line
,
1658 "field `%s' has invalid "
1659 "option `nested_ptr'\n",
1664 d
->prev_val
[2] = d
->val
;
1665 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1667 d
->val
= xasprintf ("x%d", d
->counter
++);
1668 oprintf (d
->of
, "%*s%s %s * %s%s =\n", d
->indent
, "",
1669 (nested_ptr_d
->type
->kind
== TYPE_UNION
1670 ? "union" : "struct"),
1671 nested_ptr_d
->type
->u
.s
.tag
,
1672 d
->fn_wants_lvalue
? "" : "const ",
1674 oprintf (d
->of
, "%*s", d
->indent
+ 2, "");
1675 output_escaped_param (d
, nested_ptr_d
->convert_from
,
1677 oprintf (d
->of
, ";\n");
1679 d
->process_field (nested_ptr_d
->type
, d
);
1681 if (d
->fn_wants_lvalue
)
1683 oprintf (d
->of
, "%*s%s = ", d
->indent
, "",
1685 d
->prev_val
[2] = d
->val
;
1686 output_escaped_param (d
, nested_ptr_d
->convert_to
,
1688 oprintf (d
->of
, ";\n");
1692 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1693 d
->val
= d
->prev_val
[2];
1694 d
->prev_val
[2] = oldprevval2
;
1697 d
->process_field (t
->u
.p
, d
);
1701 int loopcounter
= d
->counter
++;
1702 const char *oldval
= d
->val
;
1703 const char *oldprevval3
= d
->prev_val
[3];
1706 oprintf (d
->of
, "%*sif (%s != NULL) {\n", d
->indent
, "", d
->val
);
1708 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1709 oprintf (d
->of
, "%*sfor (i%d = 0; i%d != (size_t)(", d
->indent
, "",
1710 loopcounter
, loopcounter
);
1711 output_escaped_param (d
, length
, "length");
1712 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1714 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1716 d
->prev_val
[3] = oldval
;
1717 walk_type (t
->u
.p
, d
);
1720 d
->prev_val
[3] = oldprevval3
;
1723 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1724 d
->process_field(t
, d
);
1726 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1733 int loopcounter
= d
->counter
++;
1734 const char *oldval
= d
->val
;
1737 /* If it's an array of scalars, we optimize by not generating
1739 if (t
->u
.a
.p
->kind
== TYPE_SCALAR
)
1742 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1744 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1745 oprintf (d
->of
, "%*sfor (i%d = 0; i%d != (size_t)(", d
->indent
, "",
1746 loopcounter
, loopcounter
);
1748 output_escaped_param (d
, length
, "length");
1750 oprintf (d
->of
, "%s", t
->u
.a
.len
);
1751 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1753 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1755 walk_type (t
->u
.a
.p
, d
);
1760 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1762 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1770 const char *oldval
= d
->val
;
1771 const char *oldprevval1
= d
->prev_val
[1];
1772 const char *oldprevval2
= d
->prev_val
[2];
1773 const int union_p
= t
->kind
== TYPE_UNION
;
1774 int seen_default_p
= 0;
1777 if (! t
->u
.s
.line
.file
)
1778 error_at_line (d
->line
, "incomplete structure `%s'", t
->u
.s
.tag
);
1780 if ((d
->bitmap
& t
->u
.s
.bitmap
) != d
->bitmap
)
1782 error_at_line (d
->line
,
1783 "structure `%s' defined for mismatching languages",
1785 error_at_line (&t
->u
.s
.line
, "one structure defined here");
1788 /* Some things may also be defined in the structure's options. */
1789 for (o
= t
->u
.s
.opt
; o
; o
= o
->next
)
1790 if (! desc
&& strcmp (o
->name
, "desc") == 0)
1793 d
->prev_val
[2] = oldval
;
1794 d
->prev_val
[1] = oldprevval2
;
1799 error_at_line (d
->line
, "missing `desc' option for union `%s'",
1803 oprintf (d
->of
, "%*sswitch (", d
->indent
, "");
1804 output_escaped_param (d
, desc
, "desc");
1805 oprintf (d
->of
, ")\n");
1807 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1809 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
1812 const char *dot
= ".";
1813 const char *tagid
= NULL
;
1816 int use_param_p
= 0;
1819 d
->reorder_fn
= NULL
;
1820 for (oo
= f
->opt
; oo
; oo
= oo
->next
)
1821 if (strcmp (oo
->name
, "dot") == 0)
1823 else if (strcmp (oo
->name
, "tag") == 0)
1825 else if (strcmp (oo
->name
, "skip") == 0)
1827 else if (strcmp (oo
->name
, "default") == 0)
1829 else if (strcmp (oo
->name
, "reorder") == 0)
1830 d
->reorder_fn
= oo
->info
;
1831 else if (strncmp (oo
->name
, "use_param", 9) == 0
1832 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1838 if (union_p
&& tagid
)
1840 oprintf (d
->of
, "%*scase %s:\n", d
->indent
, "", tagid
);
1843 else if (union_p
&& default_p
)
1845 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1849 else if (! union_p
&& (default_p
|| tagid
))
1850 error_at_line (d
->line
,
1851 "can't use `%s' outside a union on field `%s'",
1852 default_p
? "default" : "tag", f
->name
);
1853 else if (union_p
&& ! (default_p
|| tagid
)
1854 && f
->type
->kind
== TYPE_SCALAR
)
1857 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1858 d
->line
->file
, d
->line
->line
, f
->name
);
1861 else if (union_p
&& ! (default_p
|| tagid
))
1862 error_at_line (d
->line
,
1863 "field `%s' is missing `tag' or `default' option",
1867 d
->val
= newval
= xasprintf ("%s%s%s", oldval
, dot
, f
->name
);
1869 d
->used_length
= false;
1871 if (union_p
&& use_param_p
&& d
->param
== NULL
)
1872 oprintf (d
->of
, "%*sgcc_unreachable ();\n", d
->indent
, "");
1874 walk_type (f
->type
, d
);
1880 oprintf (d
->of
, "%*sbreak;\n", d
->indent
, "");
1884 d
->reorder_fn
= NULL
;
1887 d
->prev_val
[1] = oldprevval1
;
1888 d
->prev_val
[2] = oldprevval2
;
1890 if (union_p
&& ! seen_default_p
)
1892 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1893 oprintf (d
->of
, "%*s break;\n", d
->indent
, "");
1897 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1903 case TYPE_LANG_STRUCT
:
1906 for (nt
= t
->u
.s
.lang_struct
; nt
; nt
= nt
->next
)
1907 if ((d
->bitmap
& nt
->u
.s
.bitmap
) == d
->bitmap
)
1910 error_at_line (d
->line
, "structure `%s' differs between languages",
1917 case TYPE_PARAM_STRUCT
:
1919 type_p
*oldparam
= d
->param
;
1921 d
->param
= t
->u
.param_struct
.param
;
1922 walk_type (t
->u
.param_struct
.stru
, d
);
1923 d
->param
= oldparam
;
1932 /* process_field routine for marking routines. */
1935 write_types_process_field (type_p f
, const struct walk_type_data
*d
)
1937 const struct write_types_data
*wtd
;
1938 const char *cast
= d
->needs_cast_p
? "(void *)" : "";
1939 wtd
= (const struct write_types_data
*) d
->cookie
;
1944 oprintf (d
->of
, "%*s%s (%s%s", d
->indent
, "",
1945 wtd
->subfield_marker_routine
, cast
, d
->val
);
1946 if (wtd
->param_prefix
)
1948 oprintf (d
->of
, ", %s", d
->prev_val
[3]);
1951 oprintf (d
->of
, ", gt_%s_", wtd
->param_prefix
);
1952 output_mangled_typename (d
->of
, d
->orig_s
);
1955 oprintf (d
->of
, ", gt_%sa_%s", wtd
->param_prefix
, d
->prev_val
[0]);
1957 if (f
->u
.p
->kind
== TYPE_PARAM_STRUCT
1958 && f
->u
.p
->u
.s
.line
.file
!= NULL
)
1960 oprintf (d
->of
, ", gt_e_");
1961 output_mangled_typename (d
->of
, f
);
1963 else if (UNION_OR_STRUCT_P (f
)
1964 && f
->u
.p
->u
.s
.line
.file
!= NULL
)
1966 oprintf (d
->of
, ", gt_ggc_e_");
1967 output_mangled_typename (d
->of
, f
);
1970 oprintf (d
->of
, ", gt_types_enum_last");
1972 oprintf (d
->of
, ");\n");
1973 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1974 oprintf (d
->of
, "%*s%s (%s%s, %s, %s);\n", d
->indent
, "",
1975 wtd
->reorder_note_routine
, cast
, d
->val
,
1976 d
->prev_val
[3], d
->reorder_fn
);
1980 if (wtd
->param_prefix
== NULL
)
1985 case TYPE_LANG_STRUCT
:
1986 case TYPE_PARAM_STRUCT
:
1987 oprintf (d
->of
, "%*sgt_%s_", d
->indent
, "", wtd
->prefix
);
1988 output_mangled_typename (d
->of
, f
);
1989 oprintf (d
->of
, " (%s%s);\n", cast
, d
->val
);
1990 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1991 oprintf (d
->of
, "%*s%s (%s%s, %s%s, %s);\n", d
->indent
, "",
1992 wtd
->reorder_note_routine
, cast
, d
->val
, cast
, d
->val
,
2004 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
2007 output_type_enum (outf_p of
, type_p s
)
2009 if (s
->kind
== TYPE_PARAM_STRUCT
&& s
->u
.s
.line
.file
!= NULL
)
2011 oprintf (of
, ", gt_e_");
2012 output_mangled_typename (of
, s
);
2014 else if (UNION_OR_STRUCT_P (s
) && s
->u
.s
.line
.file
!= NULL
)
2016 oprintf (of
, ", gt_ggc_e_");
2017 output_mangled_typename (of
, s
);
2020 oprintf (of
, ", gt_types_enum_last");
2023 /* For S, a structure that's part of ORIG_S, and using parameters
2024 PARAM, write out a routine that:
2025 - Takes a parameter, a void * but actually of type *S
2026 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2027 field of S or its substructures and (in some cases) things
2028 that are pointed to by S.
2032 write_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
,
2033 const struct write_types_data
*wtd
)
2035 const char *fn
= s
->u
.s
.line
.file
;
2037 const char *chain_next
= NULL
;
2038 const char *chain_prev
= NULL
;
2040 struct walk_type_data d
;
2042 /* This is a hack, and not the good kind either. */
2043 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
2044 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
2045 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
2046 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2048 memset (&d
, 0, sizeof (d
));
2049 d
.of
= get_output_file_with_visibility (fn
);
2051 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2052 if (strcmp (opt
->name
, "chain_next") == 0)
2053 chain_next
= opt
->info
;
2054 else if (strcmp (opt
->name
, "chain_prev") == 0)
2055 chain_prev
= opt
->info
;
2057 if (chain_prev
!= NULL
&& chain_next
== NULL
)
2058 error_at_line (&s
->u
.s
.line
, "chain_prev without chain_next");
2060 d
.process_field
= write_types_process_field
;
2064 d
.line
= &s
->u
.s
.line
;
2065 d
.bitmap
= s
->u
.s
.bitmap
;
2067 d
.prev_val
[0] = "*x";
2068 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2069 d
.prev_val
[3] = "x";
2072 oprintf (d
.of
, "\n");
2073 oprintf (d
.of
, "void\n");
2075 oprintf (d
.of
, "gt_%sx_%s", wtd
->prefix
, orig_s
->u
.s
.tag
);
2078 oprintf (d
.of
, "gt_%s_", wtd
->prefix
);
2079 output_mangled_typename (d
.of
, orig_s
);
2081 oprintf (d
.of
, " (void *x_p)\n");
2082 oprintf (d
.of
, "{\n");
2083 oprintf (d
.of
, " %s %s * %sx = (%s %s *)x_p;\n",
2084 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2085 chain_next
== NULL
? "const " : "",
2086 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2087 if (chain_next
!= NULL
)
2088 oprintf (d
.of
, " %s %s * xlimit = x;\n",
2089 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2090 if (chain_next
== NULL
)
2092 oprintf (d
.of
, " if (%s (x", wtd
->marker_routine
);
2093 if (wtd
->param_prefix
)
2095 oprintf (d
.of
, ", x, gt_%s_", wtd
->param_prefix
);
2096 output_mangled_typename (d
.of
, orig_s
);
2097 output_type_enum (d
.of
, orig_s
);
2099 oprintf (d
.of
, "))\n");
2103 oprintf (d
.of
, " while (%s (xlimit", wtd
->marker_routine
);
2104 if (wtd
->param_prefix
)
2106 oprintf (d
.of
, ", xlimit, gt_%s_", wtd
->param_prefix
);
2107 output_mangled_typename (d
.of
, orig_s
);
2108 output_type_enum (d
.of
, orig_s
);
2110 oprintf (d
.of
, "))\n");
2111 oprintf (d
.of
, " xlimit = (");
2112 d
.prev_val
[2] = "*xlimit";
2113 output_escaped_param (&d
, chain_next
, "chain_next");
2114 oprintf (d
.of
, ");\n");
2115 if (chain_prev
!= NULL
)
2117 oprintf (d
.of
, " if (x != xlimit)\n");
2118 oprintf (d
.of
, " for (;;)\n");
2119 oprintf (d
.of
, " {\n");
2120 oprintf (d
.of
, " %s %s * const xprev = (",
2121 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2123 d
.prev_val
[2] = "*x";
2124 output_escaped_param (&d
, chain_prev
, "chain_prev");
2125 oprintf (d
.of
, ");\n");
2126 oprintf (d
.of
, " if (xprev == NULL) break;\n");
2127 oprintf (d
.of
, " x = xprev;\n");
2128 oprintf (d
.of
, " (void) %s (xprev",
2129 wtd
->marker_routine
);
2130 if (wtd
->param_prefix
)
2132 oprintf (d
.of
, ", xprev, gt_%s_", wtd
->param_prefix
);
2133 output_mangled_typename (d
.of
, orig_s
);
2134 output_type_enum (d
.of
, orig_s
);
2136 oprintf (d
.of
, ");\n");
2137 oprintf (d
.of
, " }\n");
2139 oprintf (d
.of
, " while (x != xlimit)\n");
2141 oprintf (d
.of
, " {\n");
2143 d
.prev_val
[2] = "*x";
2147 if (chain_next
!= NULL
)
2149 oprintf (d
.of
, " x = (");
2150 output_escaped_param (&d
, chain_next
, "chain_next");
2151 oprintf (d
.of
, ");\n");
2154 oprintf (d
.of
, " }\n");
2155 oprintf (d
.of
, "}\n");
2158 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2161 write_types (type_p structures
, type_p param_structs
,
2162 const struct write_types_data
*wtd
)
2166 oprintf (header_file
, "\n/* %s*/\n", wtd
->comment
);
2167 for (s
= structures
; s
; s
= s
->next
)
2168 if (s
->gc_used
== GC_POINTED_TO
2169 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2173 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2174 && s
->u
.s
.line
.file
== NULL
)
2177 oprintf (header_file
, "#define gt_%s_", wtd
->prefix
);
2178 output_mangled_typename (header_file
, s
);
2179 oprintf (header_file
, "(X) do { \\\n");
2180 oprintf (header_file
,
2181 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd
->prefix
,
2183 oprintf (header_file
,
2186 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2187 if (strcmp (opt
->name
, "ptr_alias") == 0)
2189 type_p t
= (type_p
) opt
->info
;
2190 if (t
->kind
== TYPE_STRUCT
2191 || t
->kind
== TYPE_UNION
2192 || t
->kind
== TYPE_LANG_STRUCT
)
2193 oprintf (header_file
,
2194 "#define gt_%sx_%s gt_%sx_%s\n",
2195 wtd
->prefix
, s
->u
.s
.tag
, wtd
->prefix
, t
->u
.s
.tag
);
2197 error_at_line (&s
->u
.s
.line
,
2198 "structure alias is not a structure");
2204 /* Declare the marker procedure only once. */
2205 oprintf (header_file
,
2206 "extern void gt_%sx_%s (void *);\n",
2207 wtd
->prefix
, s
->u
.s
.tag
);
2209 if (s
->u
.s
.line
.file
== NULL
)
2211 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2216 if (s
->kind
== TYPE_LANG_STRUCT
)
2219 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2220 write_func_for_structure (s
, ss
, NULL
, wtd
);
2223 write_func_for_structure (s
, s
, NULL
, wtd
);
2226 for (s
= param_structs
; s
; s
= s
->next
)
2227 if (s
->gc_used
== GC_POINTED_TO
)
2229 type_p
* param
= s
->u
.param_struct
.param
;
2230 type_p stru
= s
->u
.param_struct
.stru
;
2232 /* Declare the marker procedure. */
2233 oprintf (header_file
, "extern void gt_%s_", wtd
->prefix
);
2234 output_mangled_typename (header_file
, s
);
2235 oprintf (header_file
, " (void *);\n");
2237 if (stru
->u
.s
.line
.file
== NULL
)
2239 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2244 if (stru
->kind
== TYPE_LANG_STRUCT
)
2247 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2248 write_func_for_structure (s
, ss
, param
, wtd
);
2251 write_func_for_structure (s
, stru
, param
, wtd
);
2255 static const struct write_types_data ggc_wtd
=
2257 "ggc_m", NULL
, "ggc_mark", "ggc_test_and_set_mark", NULL
,
2258 "GC marker procedures. "
2261 static const struct write_types_data pch_wtd
=
2263 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2264 "gt_pch_note_reorder",
2265 "PCH type-walking procedures. "
2268 /* Write out the local pointer-walking routines. */
2270 /* process_field routine for local pointer-walking. */
2273 write_types_local_process_field (type_p f
, const struct walk_type_data
*d
)
2280 case TYPE_LANG_STRUCT
:
2281 case TYPE_PARAM_STRUCT
:
2283 oprintf (d
->of
, "%*sif ((void *)(%s) == this_obj)\n", d
->indent
, "",
2285 oprintf (d
->of
, "%*s op (&(%s), cookie);\n", d
->indent
, "", d
->val
);
2296 /* For S, a structure that's part of ORIG_S, and using parameters
2297 PARAM, write out a routine that:
2298 - Is of type gt_note_pointers
2299 - Calls PROCESS_FIELD on each field of S or its substructures.
2303 write_local_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
)
2305 const char *fn
= s
->u
.s
.line
.file
;
2307 struct walk_type_data d
;
2309 /* This is a hack, and not the good kind either. */
2310 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
2311 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
2312 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
2313 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2315 memset (&d
, 0, sizeof (d
));
2316 d
.of
= get_output_file_with_visibility (fn
);
2318 d
.process_field
= write_types_local_process_field
;
2320 d
.line
= &s
->u
.s
.line
;
2321 d
.bitmap
= s
->u
.s
.bitmap
;
2323 d
.prev_val
[0] = d
.prev_val
[2] = "*x";
2324 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2325 d
.prev_val
[3] = "x";
2327 d
.fn_wants_lvalue
= true;
2329 oprintf (d
.of
, "\n");
2330 oprintf (d
.of
, "void\n");
2331 oprintf (d
.of
, "gt_pch_p_");
2332 output_mangled_typename (d
.of
, orig_s
);
2333 oprintf (d
.of
, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2335 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2336 "\tATTRIBUTE_UNUSED void *cookie)\n");
2337 oprintf (d
.of
, "{\n");
2338 oprintf (d
.of
, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2339 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2340 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2343 oprintf (d
.of
, "}\n");
2346 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2349 write_local (type_p structures
, type_p param_structs
)
2353 oprintf (header_file
, "\n/* Local pointer-walking routines. */\n");
2354 for (s
= structures
; s
; s
= s
->next
)
2355 if (s
->gc_used
== GC_POINTED_TO
2356 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2360 if (s
->u
.s
.line
.file
== NULL
)
2363 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2364 if (strcmp (opt
->name
, "ptr_alias") == 0)
2366 type_p t
= (type_p
) opt
->info
;
2367 if (t
->kind
== TYPE_STRUCT
2368 || t
->kind
== TYPE_UNION
2369 || t
->kind
== TYPE_LANG_STRUCT
)
2371 oprintf (header_file
, "#define gt_pch_p_");
2372 output_mangled_typename (header_file
, s
);
2373 oprintf (header_file
, " gt_pch_p_");
2374 output_mangled_typename (header_file
, t
);
2375 oprintf (header_file
, "\n");
2378 error_at_line (&s
->u
.s
.line
,
2379 "structure alias is not a structure");
2385 /* Declare the marker procedure only once. */
2386 oprintf (header_file
, "extern void gt_pch_p_");
2387 output_mangled_typename (header_file
, s
);
2388 oprintf (header_file
,
2389 "\n (void *, void *, gt_pointer_operator, void *);\n");
2391 if (s
->kind
== TYPE_LANG_STRUCT
)
2394 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2395 write_local_func_for_structure (s
, ss
, NULL
);
2398 write_local_func_for_structure (s
, s
, NULL
);
2401 for (s
= param_structs
; s
; s
= s
->next
)
2402 if (s
->gc_used
== GC_POINTED_TO
)
2404 type_p
* param
= s
->u
.param_struct
.param
;
2405 type_p stru
= s
->u
.param_struct
.stru
;
2407 /* Declare the marker procedure. */
2408 oprintf (header_file
, "extern void gt_pch_p_");
2409 output_mangled_typename (header_file
, s
);
2410 oprintf (header_file
,
2411 "\n (void *, void *, gt_pointer_operator, void *);\n");
2413 if (stru
->u
.s
.line
.file
== NULL
)
2415 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2420 if (stru
->kind
== TYPE_LANG_STRUCT
)
2423 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2424 write_local_func_for_structure (s
, ss
, param
);
2427 write_local_func_for_structure (s
, stru
, param
);
2431 /* Write out the 'enum' definition for gt_types_enum. */
2434 write_enum_defn (type_p structures
, type_p param_structs
)
2438 oprintf (header_file
, "\n/* Enumeration of types known. */\n");
2439 oprintf (header_file
, "enum gt_types_enum {\n");
2440 for (s
= structures
; s
; s
= s
->next
)
2441 if (s
->gc_used
== GC_POINTED_TO
2442 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2444 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2445 && s
->u
.s
.line
.file
== NULL
)
2448 oprintf (header_file
, " gt_ggc_e_");
2449 output_mangled_typename (header_file
, s
);
2450 oprintf (header_file
, ", \n");
2452 for (s
= param_structs
; s
; s
= s
->next
)
2453 if (s
->gc_used
== GC_POINTED_TO
)
2455 oprintf (header_file
, " gt_e_");
2456 output_mangled_typename (header_file
, s
);
2457 oprintf (header_file
, ", \n");
2459 oprintf (header_file
, " gt_types_enum_last\n");
2460 oprintf (header_file
, "};\n");
2463 /* Might T contain any non-pointer elements? */
2466 contains_scalar_p (type_p t
)
2474 return contains_scalar_p (t
->u
.a
.p
);
2476 /* Could also check for structures that have no non-pointer
2477 fields, but there aren't enough of those to worry about. */
2482 /* Mangle FN and print it to F. */
2485 put_mangled_filename (outf_p f
, const char *fn
)
2487 const char *name
= get_output_file_name (fn
);
2488 for (; *name
!= 0; name
++)
2489 if (ISALNUM (*name
))
2490 oprintf (f
, "%c", *name
);
2492 oprintf (f
, "%c", '_');
2495 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2496 LASTNAME, and NAME are all strings to insert in various places in
2497 the resulting code. */
2500 finish_root_table (struct flist
*flp
, const char *pfx
, const char *lastname
,
2501 const char *tname
, const char *name
)
2505 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2506 if (fli2
->started_p
)
2508 oprintf (fli2
->f
, " %s\n", lastname
);
2509 oprintf (fli2
->f
, "};\n\n");
2512 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2513 if (fli2
->started_p
)
2515 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2518 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2521 oprintf (base_files
[fnum
],
2522 "extern const struct %s gt_%s_",
2524 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2525 oprintf (base_files
[fnum
], "[];\n");
2531 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2532 oprintf (base_files
[fnum
],
2533 "const struct %s * const %s[] = {\n",
2538 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2539 if (fli2
->started_p
)
2541 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2544 fli2
->started_p
= 0;
2546 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2549 oprintf (base_files
[fnum
], " gt_%s_", pfx
);
2550 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2551 oprintf (base_files
[fnum
], ",\n");
2557 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2559 oprintf (base_files
[fnum
], " NULL\n");
2560 oprintf (base_files
[fnum
], "};\n");
2565 /* Write out to F the table entry and any marker routines needed to
2566 mark NAME as TYPE. The original variable is V, at LINE.
2567 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2568 is nonzero iff we are building the root table for hash table caches. */
2571 write_root (outf_p f
, pair_p v
, type_p type
, const char *name
, int has_length
,
2572 struct fileloc
*line
, const char *if_marked
)
2579 for (fld
= type
->u
.s
.fields
; fld
; fld
= fld
->next
)
2582 const char *desc
= NULL
;
2585 for (o
= fld
->opt
; o
; o
= o
->next
)
2586 if (strcmp (o
->name
, "skip") == 0)
2588 else if (strcmp (o
->name
, "desc") == 0)
2591 error_at_line (line
,
2592 "field `%s' of global `%s' has unknown option `%s'",
2593 fld
->name
, name
, o
->name
);
2597 else if (desc
&& fld
->type
->kind
== TYPE_UNION
)
2599 pair_p validf
= NULL
;
2602 for (ufld
= fld
->type
->u
.s
.fields
; ufld
; ufld
= ufld
->next
)
2604 const char *tag
= NULL
;
2607 for (oo
= ufld
->opt
; oo
; oo
= oo
->next
)
2608 if (strcmp (oo
->name
, "tag") == 0)
2610 if (tag
== NULL
|| strcmp (tag
, desc
) != 0)
2613 error_at_line (line
,
2614 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2615 name
, fld
->name
, validf
->name
,
2616 name
, fld
->name
, ufld
->name
,
2623 newname
= xasprintf ("%s.%s.%s",
2624 name
, fld
->name
, validf
->name
);
2625 write_root (f
, v
, validf
->type
, newname
, 0, line
,
2631 error_at_line (line
,
2632 "global `%s.%s' has `desc' option but is not union",
2637 newname
= xasprintf ("%s.%s", name
, fld
->name
);
2638 write_root (f
, v
, fld
->type
, newname
, 0, line
, if_marked
);
2648 newname
= xasprintf ("%s[0]", name
);
2649 write_root (f
, v
, type
->u
.a
.p
, newname
, has_length
, line
, if_marked
);
2658 oprintf (f
, " {\n");
2659 oprintf (f
, " &%s,\n", name
);
2662 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2664 oprintf (f
, " * (%s)", ap
->u
.a
.len
);
2665 else if (ap
== v
->type
)
2666 oprintf (f
, " * ARRAY_SIZE (%s)", v
->name
);
2668 oprintf (f
, " sizeof (%s", v
->name
);
2669 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2671 oprintf (f
, "),\n");
2675 if (! has_length
&& UNION_OR_STRUCT_P (tp
))
2677 oprintf (f
, " >_ggc_mx_%s,\n", tp
->u
.s
.tag
);
2678 oprintf (f
, " >_pch_nx_%s", tp
->u
.s
.tag
);
2680 else if (! has_length
&& tp
->kind
== TYPE_PARAM_STRUCT
)
2682 oprintf (f
, " >_ggc_m_");
2683 output_mangled_typename (f
, tp
);
2684 oprintf (f
, ",\n >_pch_n_");
2685 output_mangled_typename (f
, tp
);
2688 && (tp
->kind
== TYPE_POINTER
|| UNION_OR_STRUCT_P (tp
)))
2690 oprintf (f
, " >_ggc_ma_%s,\n", name
);
2691 oprintf (f
, " >_pch_na_%s", name
);
2695 error_at_line (line
,
2696 "global `%s' is pointer to unimplemented type",
2700 oprintf (f
, ",\n &%s", if_marked
);
2701 oprintf (f
, "\n },\n");
2707 oprintf (f
, " {\n");
2708 oprintf (f
, " &%s,\n", name
);
2709 oprintf (f
, " 1, \n");
2710 oprintf (f
, " sizeof (%s),\n", v
->name
);
2711 oprintf (f
, " >_ggc_m_S,\n");
2712 oprintf (f
, " (gt_pointer_walker) >_pch_n_S\n");
2713 oprintf (f
, " },\n");
2721 error_at_line (line
,
2722 "global `%s' is unimplemented type",
2727 /* This generates a routine to walk an array. */
2730 write_array (outf_p f
, pair_p v
, const struct write_types_data
*wtd
)
2732 struct walk_type_data d
;
2735 memset (&d
, 0, sizeof (d
));
2741 d
.bitmap
= get_base_file_bitmap (v
->line
.file
);
2744 d
.prev_val
[3] = prevval3
= xasprintf ("&%s", v
->name
);
2746 if (wtd
->param_prefix
)
2748 oprintf (f
, "static void gt_%sa_%s\n", wtd
->param_prefix
, v
->name
);
2750 " (void *, void *, gt_pointer_operator, void *);\n");
2751 oprintf (f
, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2752 wtd
->param_prefix
, v
->name
);
2754 " ATTRIBUTE_UNUSED void *x_p,\n"
2755 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2756 " ATTRIBUTE_UNUSED void * cookie)\n");
2757 oprintf (d
.of
, "{\n");
2758 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2759 d
.process_field
= write_types_local_process_field
;
2760 walk_type (v
->type
, &d
);
2761 oprintf (f
, "}\n\n");
2765 oprintf (f
, "static void gt_%sa_%s (void *);\n",
2766 wtd
->prefix
, v
->name
);
2767 oprintf (f
, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2768 wtd
->prefix
, v
->name
);
2770 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2771 d
.process_field
= write_types_process_field
;
2772 walk_type (v
->type
, &d
);
2774 oprintf (f
, "}\n\n");
2777 /* Output a table describing the locations and types of VARIABLES. */
2780 write_roots (pair_p variables
)
2783 struct flist
*flp
= NULL
;
2785 for (v
= variables
; v
; v
= v
->next
)
2787 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2789 const char *length
= NULL
;
2790 int deletable_p
= 0;
2793 for (o
= v
->opt
; o
; o
= o
->next
)
2794 if (strcmp (o
->name
, "length") == 0)
2796 else if (strcmp (o
->name
, "deletable") == 0)
2798 else if (strcmp (o
->name
, "param_is") == 0)
2800 else if (strncmp (o
->name
, "param", 5) == 0
2801 && ISDIGIT (o
->name
[5])
2802 && strcmp (o
->name
+ 6, "_is") == 0)
2804 else if (strcmp (o
->name
, "if_marked") == 0)
2807 error_at_line (&v
->line
,
2808 "global `%s' has unknown option `%s'",
2811 for (fli
= flp
; fli
; fli
= fli
->next
)
2816 fli
= XNEW (struct flist
);
2820 fli
->name
= v
->line
.file
;
2823 oprintf (f
, "\n/* GC roots. */\n\n");
2828 && v
->type
->kind
== TYPE_POINTER
2829 && (v
->type
->u
.p
->kind
== TYPE_POINTER
2830 || v
->type
->u
.p
->kind
== TYPE_STRUCT
))
2832 write_array (f
, v
, &ggc_wtd
);
2833 write_array (f
, v
, &pch_wtd
);
2837 for (v
= variables
; v
; v
= v
->next
)
2839 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2845 for (o
= v
->opt
; o
; o
= o
->next
)
2846 if (strcmp (o
->name
, "length") == 0)
2848 else if (strcmp (o
->name
, "deletable") == 0
2849 || strcmp (o
->name
, "if_marked") == 0)
2855 for (fli
= flp
; fli
; fli
= fli
->next
)
2858 if (! fli
->started_p
)
2862 oprintf (f
, "const struct ggc_root_tab gt_ggc_r_");
2863 put_mangled_filename (f
, v
->line
.file
);
2864 oprintf (f
, "[] = {\n");
2867 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2870 finish_root_table (flp
, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2873 for (v
= variables
; v
; v
= v
->next
)
2875 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2880 for (o
= v
->opt
; o
; o
= o
->next
)
2881 if (strcmp (o
->name
, "deletable") == 0)
2883 else if (strcmp (o
->name
, "if_marked") == 0)
2889 for (fli
= flp
; fli
; fli
= fli
->next
)
2892 if (! fli
->started_p
)
2896 oprintf (f
, "const struct ggc_root_tab gt_ggc_rd_");
2897 put_mangled_filename (f
, v
->line
.file
);
2898 oprintf (f
, "[] = {\n");
2901 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2905 finish_root_table (flp
, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2906 "gt_ggc_deletable_rtab");
2908 for (v
= variables
; v
; v
= v
->next
)
2910 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2912 const char *if_marked
= NULL
;
2916 for (o
= v
->opt
; o
; o
= o
->next
)
2917 if (strcmp (o
->name
, "length") == 0)
2919 else if (strcmp (o
->name
, "if_marked") == 0)
2920 if_marked
= o
->info
;
2922 if (if_marked
== NULL
)
2925 if (v
->type
->kind
!= TYPE_POINTER
2926 || v
->type
->u
.p
->kind
!= TYPE_PARAM_STRUCT
2927 || v
->type
->u
.p
->u
.param_struct
.stru
!= find_structure ("htab", 0))
2929 error_at_line (&v
->line
, "if_marked option used but not hash table");
2933 for (fli
= flp
; fli
; fli
= fli
->next
)
2936 if (! fli
->started_p
)
2940 oprintf (f
, "const struct ggc_cache_tab gt_ggc_rc_");
2941 put_mangled_filename (f
, v
->line
.file
);
2942 oprintf (f
, "[] = {\n");
2945 write_root (f
, v
, v
->type
->u
.p
->u
.param_struct
.param
[0],
2946 v
->name
, length_p
, &v
->line
, if_marked
);
2949 finish_root_table (flp
, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2950 "gt_ggc_cache_rtab");
2952 for (v
= variables
; v
; v
= v
->next
)
2954 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2957 int if_marked_p
= 0;
2960 for (o
= v
->opt
; o
; o
= o
->next
)
2961 if (strcmp (o
->name
, "length") == 0)
2963 else if (strcmp (o
->name
, "if_marked") == 0)
2969 for (fli
= flp
; fli
; fli
= fli
->next
)
2972 if (! fli
->started_p
)
2976 oprintf (f
, "const struct ggc_root_tab gt_pch_rc_");
2977 put_mangled_filename (f
, v
->line
.file
);
2978 oprintf (f
, "[] = {\n");
2981 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2984 finish_root_table (flp
, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2985 "gt_pch_cache_rtab");
2987 for (v
= variables
; v
; v
= v
->next
)
2989 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2994 for (o
= v
->opt
; o
; o
= o
->next
)
2995 if (strcmp (o
->name
, "deletable") == 0
2996 || strcmp (o
->name
, "if_marked") == 0)
3002 if (! contains_scalar_p (v
->type
))
3005 for (fli
= flp
; fli
; fli
= fli
->next
)
3008 if (! fli
->started_p
)
3012 oprintf (f
, "const struct ggc_root_tab gt_pch_rs_");
3013 put_mangled_filename (f
, v
->line
.file
);
3014 oprintf (f
, "[] = {\n");
3017 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3021 finish_root_table (flp
, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3022 "gt_pch_scalar_rtab");
3026 extern int main (int argc
, char **argv
);
3028 main(int ARG_UNUSED (argc
), char ** ARG_UNUSED (argv
))
3031 static struct fileloc pos
= { __FILE__
, __LINE__
};
3036 srcdir_len
= strlen (srcdir
);
3038 do_scalar_typedef ("CUMULATIVE_ARGS", &pos
);
3039 do_scalar_typedef ("REAL_VALUE_TYPE", &pos
);
3040 do_scalar_typedef ("double_int", &pos
);
3041 do_scalar_typedef ("uint8", &pos
);
3042 do_scalar_typedef ("jword", &pos
);
3043 do_scalar_typedef ("JCF_u2", &pos
);
3044 #ifdef USE_MAPPED_LOCATION
3045 do_scalar_typedef ("location_t", &pos
);
3046 do_scalar_typedef ("source_locus", &pos
);
3048 do_scalar_typedef ("void", &pos
);
3050 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos
)), &pos
);
3052 do_typedef ("HARD_REG_SET", create_array (
3053 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3056 for (i
= 0; i
< NUM_GT_FILES
; i
++)
3059 /* Omit if already seen. */
3060 for (j
= 0; j
< i
; j
++)
3062 if (!strcmp (all_files
[i
], all_files
[j
]))
3069 parse_file (all_files
[i
]);
3070 #ifndef USE_MAPPED_LOCATION
3071 /* temporary kludge - gengtype doesn't handle conditionals.
3072 Manually add source_locus *after* we've processed input.h. */
3074 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos
)), &pos
);
3081 set_gc_used (variables
);
3084 write_enum_defn (structures
, param_structs
);
3085 write_types (structures
, param_structs
, &ggc_wtd
);
3086 write_types (structures
, param_structs
, &pch_wtd
);
3087 write_local (structures
, param_structs
);
3088 write_roots (variables
);
3090 close_output_files ();
3092 return (hit_error
!= 0);