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_EXPECTED_VALUE
:
523 case NOTE_INSN_VAR_LOCATION
:
524 note_flds
= create_field (note_flds
, rtx_tp
, "rt_rtx");
528 note_flds
= create_field (note_flds
, scalar_tp
, "rt_int");
531 /* NOTE_INSN_MAX is used as the default field for line
533 if (c
== NOTE_INSN_MAX
)
534 note_flds
->opt
= create_option (nodot
, "default", "");
536 note_flds
->opt
= create_option (nodot
, "tag", note_insn_name
[c
]);
538 note_union_tp
= new_structure ("rtx_def_note_subunion", 1,
539 &lexer_line
, note_flds
, NULL
);
541 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */
545 sym_flds
= create_field (NULL
, tree_tp
, "rt_tree");
546 sym_flds
->opt
= create_option (nodot
, "default", "");
548 sym_flds
= create_field (sym_flds
, constant_tp
, "rt_constant");
549 sym_flds
->opt
= create_option (nodot
, "tag", "1");
551 symbol_union_tp
= new_structure ("rtx_def_symbol_subunion", 1,
552 &lexer_line
, sym_flds
, NULL
);
554 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
556 pair_p subfields
= NULL
;
557 size_t aindex
, nmindex
;
562 for (aindex
= 0; aindex
< strlen (rtx_format
[i
]); aindex
++)
567 switch (rtx_format
[i
][aindex
])
578 if (i
== MEM
&& aindex
== 1)
579 t
= mem_attrs_tp
, subname
= "rt_mem";
580 else if (i
== JUMP_INSN
&& aindex
== 9)
581 t
= rtx_tp
, subname
= "rt_rtx";
582 else if (i
== CODE_LABEL
&& aindex
== 4)
583 t
= scalar_tp
, subname
= "rt_int";
584 else if (i
== CODE_LABEL
&& aindex
== 5)
585 t
= rtx_tp
, subname
= "rt_rtx";
586 else if (i
== LABEL_REF
587 && (aindex
== 1 || aindex
== 2))
588 t
= rtx_tp
, subname
= "rt_rtx";
589 else if (i
== NOTE
&& aindex
== 4)
590 t
= note_union_tp
, subname
= "";
591 else if (i
== NOTE
&& aindex
>= 7)
592 t
= scalar_tp
, subname
= "rt_int";
593 else if (i
== ADDR_DIFF_VEC
&& aindex
== 4)
594 t
= scalar_tp
, subname
= "rt_int";
595 else if (i
== VALUE
&& aindex
== 0)
596 t
= scalar_tp
, subname
= "rt_int";
597 else if (i
== REG
&& aindex
== 1)
598 t
= scalar_tp
, subname
= "rt_int";
599 else if (i
== REG
&& aindex
== 2)
600 t
= reg_attrs_tp
, subname
= "rt_reg";
601 else if (i
== SCRATCH
&& aindex
== 0)
602 t
= scalar_tp
, subname
= "rt_int";
603 else if (i
== SYMBOL_REF
&& aindex
== 1)
604 t
= scalar_tp
, subname
= "rt_int";
605 else if (i
== SYMBOL_REF
&& aindex
== 2)
606 t
= symbol_union_tp
, subname
= "";
607 else if (i
== BARRIER
&& aindex
>= 3)
608 t
= scalar_tp
, subname
= "rt_int";
611 error_at_line (&lexer_line
,
612 "rtx type `%s' has `0' in position %lu, can't handle",
613 rtx_name
[i
], (unsigned long) aindex
);
635 subname
= "rt_rtvec";
654 error_at_line (&lexer_line
,
655 "rtx type `%s' has `%c' in position %lu, can't handle",
656 rtx_name
[i
], rtx_format
[i
][aindex
],
657 (unsigned long)aindex
);
663 subfields
= create_field (subfields
, t
,
664 xasprintf (".fld[%lu].%s",
665 (unsigned long) aindex
,
667 subfields
->opt
= nodot
;
668 if (t
== note_union_tp
)
669 subfields
->opt
= create_option (subfields
->opt
, "desc",
670 "NOTE_LINE_NUMBER (&%0)");
671 if (t
== symbol_union_tp
)
672 subfields
->opt
= create_option (subfields
->opt
, "desc",
673 "CONSTANT_POOL_ADDRESS_P (&%0)");
678 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
679 type_p field_tp
= find_structure ("block_symbol", 0);
681 = create_optional_field (subfields
, field_tp
, "block_sym",
682 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
685 sname
= xasprintf ("rtx_def_%s", rtx_name
[i
]);
686 substruct
= new_structure (sname
, 0, &lexer_line
, subfields
, NULL
);
688 ftag
= xstrdup (rtx_name
[i
]);
689 for (nmindex
= 0; nmindex
< strlen (ftag
); nmindex
++)
690 ftag
[nmindex
] = TOUPPER (ftag
[nmindex
]);
692 flds
= create_field (flds
, substruct
, "");
693 flds
->opt
= create_option (nodot
, "tag", ftag
);
696 return new_structure ("rtx_def_subunion", 1, &lexer_line
, flds
, nodot
);
699 /* Handle `special("tree_exp")'. This is a special case for
700 field `operands' of struct tree_exp, which although it claims to contain
701 pointers to trees, actually sometimes contains pointers to RTL too.
702 Passed T, the old type of the field, and OPT its options. Returns
703 a new type for the field. */
706 adjust_field_tree_exp (type_p t
, options_p opt ATTRIBUTE_UNUSED
)
711 if (t
->kind
!= TYPE_ARRAY
)
713 error_at_line (&lexer_line
,
714 "special `tree_exp' must be applied to an array");
718 nodot
= create_option (NULL
, "dot", "");
720 flds
= create_field (NULL
, t
, "");
721 flds
->opt
= create_option (nodot
, "length",
722 "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))");
723 flds
->opt
= create_option (flds
->opt
, "default", "");
725 return new_structure ("tree_exp_subunion", 1, &lexer_line
, flds
, nodot
);
728 /* Perform any special processing on a type T, about to become the type
729 of a field. Return the appropriate type for the field.
731 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
732 - Similarly for arrays of pointer-to-char;
733 - Converts structures for which a parameter is provided to
735 - Handles "special" options.
739 adjust_field_type (type_p t
, options_p opt
)
742 const int pointer_p
= t
->kind
== TYPE_POINTER
;
743 type_p params
[NUM_PARAM
];
747 for (i
= 0; i
< NUM_PARAM
; i
++)
750 for (; opt
; opt
= opt
->next
)
751 if (strcmp (opt
->name
, "length") == 0)
753 else if (strcmp (opt
->name
, "param_is") == 0
754 || (strncmp (opt
->name
, "param", 5) == 0
755 && ISDIGIT (opt
->name
[5])
756 && strcmp (opt
->name
+ 6, "_is") == 0))
758 int num
= ISDIGIT (opt
->name
[5]) ? opt
->name
[5] - '0' : 0;
760 if (! UNION_OR_STRUCT_P (t
)
761 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
763 error_at_line (&lexer_line
,
764 "option `%s' may only be applied to structures or structure pointers",
770 if (params
[num
] != NULL
)
771 error_at_line (&lexer_line
, "duplicate `%s' option", opt
->name
);
772 if (! ISDIGIT (opt
->name
[5]))
773 params
[num
] = create_pointer ((type_p
) opt
->info
);
775 params
[num
] = (type_p
) opt
->info
;
777 else if (strcmp (opt
->name
, "special") == 0)
779 const char *special_name
= opt
->info
;
780 if (strcmp (special_name
, "tree_exp") == 0)
781 t
= adjust_field_tree_exp (t
, opt
);
782 else if (strcmp (special_name
, "rtx_def") == 0)
783 t
= adjust_field_rtx_def (t
, opt
);
785 error_at_line (&lexer_line
, "unknown special `%s'", special_name
);
794 realt
= find_param_structure (t
, params
);
795 t
= pointer_p
? create_pointer (realt
) : realt
;
800 && t
->u
.p
->kind
== TYPE_SCALAR
801 && (strcmp (t
->u
.p
->u
.sc
, "char") == 0
802 || strcmp (t
->u
.p
->u
.sc
, "unsigned char") == 0))
804 if (t
->kind
== TYPE_ARRAY
&& t
->u
.a
.p
->kind
== TYPE_POINTER
805 && t
->u
.a
.p
->u
.p
->kind
== TYPE_SCALAR
806 && (strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "char") == 0
807 || strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "unsigned char") == 0))
808 return create_array (&string_type
, t
->u
.a
.len
);
813 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
814 and information about the correspondence between token types and fields
815 in TYPEINFO. POS is used for error messages. */
818 note_yacc_type (options_p o
, pair_p fields
, pair_p typeinfo
,
824 for (p
= typeinfo
; p
; p
= p
->next
)
831 if (p
->type
== (type_p
) 1)
836 for (pp
= typeinfo
; pp
; pp
= pp
->next
)
837 if (pp
->type
!= (type_p
) 1
838 && strcmp (pp
->opt
->info
, p
->opt
->info
) == 0)
847 for (m
= fields
; m
; m
= m
->next
)
848 if (strcmp (m
->name
, p
->name
) == 0)
852 error_at_line (&p
->line
,
853 "couldn't match fieldname `%s'", p
->name
);
864 || p
->type
== (type_p
) 1)
870 do_typedef ("YYSTYPE", new_structure ("yy_union", 1, pos
, typeinfo
, o
), pos
);
873 static void process_gc_options (options_p
, enum gc_used_enum
,
874 int *, int *, int *, type_p
*);
875 static void set_gc_used_type (type_p
, enum gc_used_enum
, type_p
*);
876 static void set_gc_used (pair_p
);
878 /* Handle OPT for set_gc_used_type. */
881 process_gc_options (options_p opt
, enum gc_used_enum level
, int *maybe_undef
,
882 int *pass_param
, int *length
, type_p
*nested_ptr
)
885 for (o
= opt
; o
; o
= o
->next
)
886 if (strcmp (o
->name
, "ptr_alias") == 0 && level
== GC_POINTED_TO
)
887 set_gc_used_type ((type_p
) o
->info
, GC_POINTED_TO
, NULL
);
888 else if (strcmp (o
->name
, "maybe_undef") == 0)
890 else if (strcmp (o
->name
, "use_params") == 0)
892 else if (strcmp (o
->name
, "length") == 0)
894 else if (strcmp (o
->name
, "nested_ptr") == 0)
895 *nested_ptr
= ((const struct nested_ptr_data
*) o
->info
)->type
;
898 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
901 set_gc_used_type (type_p t
, enum gc_used_enum level
, type_p param
[NUM_PARAM
])
903 if (t
->gc_used
>= level
)
917 process_gc_options (t
->u
.s
.opt
, level
, &dummy
, &dummy
, &dummy
,
920 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
925 type_p nested_ptr
= NULL
;
926 process_gc_options (f
->opt
, level
, &maybe_undef
, &pass_param
,
927 &length
, &nested_ptr
);
929 if (nested_ptr
&& f
->type
->kind
== TYPE_POINTER
)
930 set_gc_used_type (nested_ptr
, GC_POINTED_TO
,
931 pass_param
? param
: NULL
);
932 else if (length
&& f
->type
->kind
== TYPE_POINTER
)
933 set_gc_used_type (f
->type
->u
.p
, GC_USED
, NULL
);
934 else if (maybe_undef
&& f
->type
->kind
== TYPE_POINTER
)
935 set_gc_used_type (f
->type
->u
.p
, GC_MAYBE_POINTED_TO
, NULL
);
936 else if (pass_param
&& f
->type
->kind
== TYPE_POINTER
&& param
)
937 set_gc_used_type (find_param_structure (f
->type
->u
.p
, param
),
938 GC_POINTED_TO
, NULL
);
940 set_gc_used_type (f
->type
, GC_USED
, pass_param
? param
: NULL
);
946 set_gc_used_type (t
->u
.p
, GC_POINTED_TO
, NULL
);
950 set_gc_used_type (t
->u
.a
.p
, GC_USED
, param
);
953 case TYPE_LANG_STRUCT
:
954 for (t
= t
->u
.s
.lang_struct
; t
; t
= t
->next
)
955 set_gc_used_type (t
, level
, param
);
958 case TYPE_PARAM_STRUCT
:
961 for (i
= 0; i
< NUM_PARAM
; i
++)
962 if (t
->u
.param_struct
.param
[i
] != 0)
963 set_gc_used_type (t
->u
.param_struct
.param
[i
], GC_USED
, NULL
);
965 if (t
->u
.param_struct
.stru
->gc_used
== GC_POINTED_TO
)
966 level
= GC_POINTED_TO
;
969 t
->u
.param_struct
.stru
->gc_used
= GC_UNUSED
;
970 set_gc_used_type (t
->u
.param_struct
.stru
, level
,
971 t
->u
.param_struct
.param
);
979 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
982 set_gc_used (pair_p variables
)
985 for (p
= variables
; p
; p
= p
->next
)
986 set_gc_used_type (p
->type
, GC_USED
, NULL
);
989 /* File mapping routines. For each input file, there is one output .c file
990 (but some output files have many input files), and there is one .h file
991 for the whole build. */
993 /* The list of output files. */
994 static outf_p output_files
;
996 /* The output header file that is included into pretty much every
998 static outf_p header_file
;
1000 /* Number of files specified in gtfiles. */
1001 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1003 /* Number of files in the language files array. */
1004 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1006 /* Length of srcdir name. */
1007 static int srcdir_len
= 0;
1009 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1010 outf_p base_files
[NUM_BASE_FILES
];
1012 static outf_p
create_file (const char *, const char *);
1013 static const char * get_file_basename (const char *);
1015 /* Create and return an outf_p for a new file for NAME, to be called
1019 create_file (const char *name
, const char *oname
)
1021 static const char *const hdr
[] = {
1022 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
1024 "This file is part of GCC.\n",
1026 "GCC is free software; you can redistribute it and/or modify it under\n",
1027 "the terms of the GNU General Public License as published by the Free\n",
1028 "Software Foundation; either version 2, or (at your option) any later\n",
1031 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1032 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1033 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1034 "for more details.\n",
1036 "You should have received a copy of the GNU General Public License\n",
1037 "along with GCC; see the file COPYING. If not, write to the Free\n",
1038 "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1039 "02110-1301, USA. */\n",
1041 "/* This file is machine generated. Do not edit. */\n"
1046 f
= XCNEW (struct outf
);
1047 f
->next
= output_files
;
1051 oprintf (f
, "/* Type information for %s.\n", name
);
1052 for (i
= 0; i
< ARRAY_SIZE (hdr
); i
++)
1053 oprintf (f
, "%s", hdr
[i
]);
1057 /* Print, like fprintf, to O. */
1059 oprintf (outf_p o
, const char *format
, ...)
1065 va_start (ap
, format
);
1066 slength
= xvasprintf (&s
, format
, ap
);
1068 if (o
->bufused
+ slength
> o
->buflength
)
1070 size_t new_len
= o
->buflength
;
1075 } while (o
->bufused
+ slength
>= new_len
);
1076 o
->buf
= XRESIZEVEC (char, o
->buf
, new_len
);
1077 o
->buflength
= new_len
;
1079 memcpy (o
->buf
+ o
->bufused
, s
, slength
);
1080 o
->bufused
+= slength
;
1085 /* Open the global header file and the language-specific header files. */
1088 open_base_files (void)
1092 header_file
= create_file ("GCC", "gtype-desc.h");
1094 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1095 base_files
[i
] = create_file (lang_dir_names
[i
],
1096 xasprintf ("gtype-%s.h", lang_dir_names
[i
]));
1098 /* gtype-desc.c is a little special, so we create it here. */
1100 /* The order of files here matters very much. */
1101 static const char *const ifiles
[] = {
1102 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1103 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1104 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1105 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1106 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1107 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1108 "except.h", "output.h", NULL
1110 const char *const *ifp
;
1111 outf_p gtype_desc_c
;
1113 gtype_desc_c
= create_file ("GCC", "gtype-desc.c");
1114 for (ifp
= ifiles
; *ifp
; ifp
++)
1115 oprintf (gtype_desc_c
, "#include \"%s\"\n", *ifp
);
1119 /* Determine the pathname to F relative to $(srcdir). */
1122 get_file_basename (const char *f
)
1124 const char *basename
;
1127 basename
= strrchr (f
, '/');
1134 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1140 s1
= basename
- strlen (lang_dir_names
[i
]) - 1;
1141 s2
= lang_dir_names
[i
];
1144 if (l1
>= l2
&& IS_DIR_SEPARATOR (s1
[-1]) && !memcmp (s1
, s2
, l2
))
1147 if ((basename
- f
- 1) != srcdir_len
)
1148 fatal ("filename `%s' should be preceded by $srcdir", f
);
1156 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1157 INPUT_FILE is used by <lang>.
1159 This function should be written to assume that a file _is_ used
1160 if the situation is unclear. If it wrongly assumes a file _is_ used,
1161 a linker error will result. If it wrongly assumes a file _is not_ used,
1162 some GC roots may be missed, which is a much harder-to-debug problem. */
1165 get_base_file_bitmap (const char *input_file
)
1167 const char *basename
= get_file_basename (input_file
);
1168 const char *slashpos
= strchr (basename
, '/');
1173 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1174 it belongs to the corresponding language. The file may belong to other
1175 languages as well (which is checked for below). */
1180 for (i
= 1; i
< NUM_BASE_FILES
; i
++)
1181 if ((size_t)(slashpos
- basename
) == strlen (lang_dir_names
[i
])
1182 && memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0)
1184 /* It's in a language directory, set that language. */
1189 /* If it's in any config-lang.in, then set for the languages
1194 for (j
= 0; j
< NUM_LANG_FILES
; j
++)
1196 if (!strcmp(input_file
, lang_files
[j
]))
1198 for (k
= 0; k
< NUM_BASE_FILES
; k
++)
1200 if (!strcmp(lang_dir_names
[k
], langs_for_lang_files
[j
]))
1206 /* Otherwise, set all languages. */
1208 bitmap
= (1 << NUM_BASE_FILES
) - 1;
1213 /* An output file, suitable for definitions, that can see declarations
1214 made in INPUT_FILE and is linked into every language that uses
1218 get_output_file_with_visibility (const char *input_file
)
1222 const char *basename
;
1223 const char *for_name
;
1224 const char *output_name
;
1226 /* This can happen when we need a file with visibility on a
1227 structure that we've never seen. We have to just hope that it's
1228 globally visible. */
1229 if (input_file
== NULL
)
1230 input_file
= "system.h";
1232 /* Determine the output file name. */
1233 basename
= get_file_basename (input_file
);
1235 len
= strlen (basename
);
1236 if ((len
> 2 && memcmp (basename
+len
-2, ".c", 2) == 0)
1237 || (len
> 2 && memcmp (basename
+len
-2, ".y", 2) == 0)
1238 || (len
> 3 && memcmp (basename
+len
-3, ".in", 3) == 0))
1242 output_name
= s
= xasprintf ("gt-%s", basename
);
1243 for (; *s
!= '.'; s
++)
1244 if (! ISALNUM (*s
) && *s
!= '-')
1246 memcpy (s
, ".h", sizeof (".h"));
1247 for_name
= basename
;
1249 /* Some headers get used by more than one front-end; hence, it
1250 would be inappropriate to spew them out to a single gtype-<lang>.h
1251 (and gengtype doesn't know how to direct spewage into multiple
1252 gtype-<lang>.h headers at this time). Instead, we pair up these
1253 headers with source files (and their special purpose gt-*.h headers). */
1254 else if (strcmp (basename
, "c-common.h") == 0)
1255 output_name
= "gt-c-common.h", for_name
= "c-common.c";
1256 else if (strcmp (basename
, "c-tree.h") == 0)
1257 output_name
= "gt-c-decl.h", for_name
= "c-decl.c";
1258 else if (strncmp (basename
, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename
[2])
1259 && strcmp (basename
+ 3, "cp-tree.h") == 0)
1260 output_name
= "gt-cp-tree.h", for_name
= "cp/tree.c";
1261 else if (strncmp (basename
, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename
[2])
1262 && strcmp (basename
+ 3, "decl.h") == 0)
1263 output_name
= "gt-cp-decl.h", for_name
= "cp/decl.c";
1264 else if (strncmp (basename
, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename
[2])
1265 && strcmp (basename
+ 3, "name-lookup.h") == 0)
1266 output_name
= "gt-cp-name-lookup.h", for_name
= "cp/name-lookup.c";
1267 else if (strncmp (basename
, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename
[4])
1268 && strcmp (basename
+ 5, "objc-act.h") == 0)
1269 output_name
= "gt-objc-objc-act.h", for_name
= "objc/objc-act.c";
1274 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
1275 if (memcmp (basename
, lang_dir_names
[i
], strlen (lang_dir_names
[i
])) == 0
1276 && basename
[strlen(lang_dir_names
[i
])] == '/')
1277 return base_files
[i
];
1279 output_name
= "gtype-desc.c";
1283 /* Look through to see if we've ever seen this output filename before. */
1284 for (r
= output_files
; r
; r
= r
->next
)
1285 if (strcmp (r
->name
, output_name
) == 0)
1288 /* If not, create it. */
1289 r
= create_file (for_name
, output_name
);
1294 /* The name of an output file, suitable for definitions, that can see
1295 declarations made in INPUT_FILE and is linked into every language
1296 that uses INPUT_FILE. */
1299 get_output_file_name (const char *input_file
)
1301 return get_output_file_with_visibility (input_file
)->name
;
1304 /* Copy the output to its final destination,
1305 but don't unnecessarily change modification times. */
1308 close_output_files (void)
1312 for (of
= output_files
; of
; of
= of
->next
)
1316 newfile
= fopen (of
->name
, "r");
1317 if (newfile
!= NULL
)
1322 for (i
= 0; i
< of
->bufused
; i
++)
1325 ch
= fgetc (newfile
);
1326 if (ch
== EOF
|| ch
!= (unsigned char) of
->buf
[i
])
1329 no_write_p
= i
== of
->bufused
&& fgetc (newfile
) == EOF
;
1336 newfile
= fopen (of
->name
, "w");
1337 if (newfile
== NULL
)
1339 perror ("opening output file");
1342 if (fwrite (of
->buf
, 1, of
->bufused
, newfile
) != of
->bufused
)
1344 perror ("writing output file");
1347 if (fclose (newfile
) != 0)
1349 perror ("closing output file");
1362 struct walk_type_data
;
1364 /* For scalars and strings, given the item in 'val'.
1365 For structures, given a pointer to the item in 'val'.
1366 For misc. pointers, given the item in 'val'.
1368 typedef void (*process_field_fn
)
1369 (type_p f
, const struct walk_type_data
*p
);
1370 typedef void (*func_name_fn
)
1371 (type_p s
, const struct walk_type_data
*p
);
1373 /* Parameters for write_types. */
1375 struct write_types_data
1378 const char *param_prefix
;
1379 const char *subfield_marker_routine
;
1380 const char *marker_routine
;
1381 const char *reorder_note_routine
;
1382 const char *comment
;
1385 static void output_escaped_param (struct walk_type_data
*d
,
1386 const char *, const char *);
1387 static void output_mangled_typename (outf_p
, type_p
);
1388 static void walk_type (type_p t
, struct walk_type_data
*d
);
1389 static void write_func_for_structure
1390 (type_p orig_s
, type_p s
, type_p
* param
,
1391 const struct write_types_data
*wtd
);
1392 static void write_types_process_field
1393 (type_p f
, const struct walk_type_data
*d
);
1394 static void write_types (type_p structures
,
1395 type_p param_structs
,
1396 const struct write_types_data
*wtd
);
1397 static void write_types_local_process_field
1398 (type_p f
, const struct walk_type_data
*d
);
1399 static void write_local_func_for_structure
1400 (type_p orig_s
, type_p s
, type_p
* param
);
1401 static void write_local (type_p structures
,
1402 type_p param_structs
);
1403 static void write_enum_defn (type_p structures
, type_p param_structs
);
1404 static int contains_scalar_p (type_p t
);
1405 static void put_mangled_filename (outf_p
, const char *);
1406 static void finish_root_table (struct flist
*flp
, const char *pfx
,
1407 const char *tname
, const char *lastname
,
1409 static void write_root (outf_p
, pair_p
, type_p
, const char *, int,
1410 struct fileloc
*, const char *);
1411 static void write_array (outf_p f
, pair_p v
,
1412 const struct write_types_data
*wtd
);
1413 static void write_roots (pair_p
);
1415 /* Parameters for walk_type. */
1417 struct walk_type_data
1419 process_field_fn process_field
;
1424 const char *prev_val
[4];
1427 struct fileloc
*line
;
1432 const char *reorder_fn
;
1434 bool fn_wants_lvalue
;
1437 /* Print a mangled name representing T to OF. */
1440 output_mangled_typename (outf_p of
, type_p t
)
1444 else switch (t
->kind
)
1448 output_mangled_typename (of
, t
->u
.p
);
1458 case TYPE_LANG_STRUCT
:
1459 oprintf (of
, "%lu%s", (unsigned long) strlen (t
->u
.s
.tag
), t
->u
.s
.tag
);
1461 case TYPE_PARAM_STRUCT
:
1464 for (i
= 0; i
< NUM_PARAM
; i
++)
1465 if (t
->u
.param_struct
.param
[i
] != NULL
)
1466 output_mangled_typename (of
, t
->u
.param_struct
.param
[i
]);
1467 output_mangled_typename (of
, t
->u
.param_struct
.stru
);
1475 /* Print PARAM to D->OF processing escapes. D->VAL references the
1476 current object, D->PREV_VAL the object containing the current
1477 object, ONAME is the name of the option and D->LINE is used to
1478 print error messages. */
1481 output_escaped_param (struct walk_type_data
*d
, const char *param
,
1486 for (p
= param
; *p
; p
++)
1488 oprintf (d
->of
, "%c", *p
);
1492 oprintf (d
->of
, "(%s)", d
->prev_val
[2]);
1495 oprintf (d
->of
, "(%s)", d
->prev_val
[0]);
1498 oprintf (d
->of
, "(%s)", d
->prev_val
[1]);
1502 const char *pp
= d
->val
+ strlen (d
->val
);
1503 while (pp
[-1] == ']')
1506 oprintf (d
->of
, "%s", pp
);
1510 error_at_line (d
->line
, "`%s' option contains bad escape %c%c",
1515 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1516 which is of type T. Write code to D->OF to constrain execution (at
1517 the point that D->PROCESS_FIELD is called) to the appropriate
1518 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1519 pointers to those objects. D->PREV_VAL lists the objects
1520 containing the current object, D->OPT is a list of options to
1521 apply, D->INDENT is the current indentation level, D->LINE is used
1522 to print error messages, D->BITMAP indicates which languages to
1523 print the structure for, and D->PARAM is the current parameter
1524 (from an enclosing param_is option). */
1527 walk_type (type_p t
, struct walk_type_data
*d
)
1529 const char *length
= NULL
;
1530 const char *desc
= NULL
;
1531 int maybe_undef_p
= 0;
1532 int use_param_num
= -1;
1533 int use_params_p
= 0;
1535 const struct nested_ptr_data
*nested_ptr_d
= NULL
;
1537 d
->needs_cast_p
= false;
1538 for (oo
= d
->opt
; oo
; oo
= oo
->next
)
1539 if (strcmp (oo
->name
, "length") == 0)
1541 else if (strcmp (oo
->name
, "maybe_undef") == 0)
1543 else if (strncmp (oo
->name
, "use_param", 9) == 0
1544 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1545 use_param_num
= oo
->name
[9] == '\0' ? 0 : oo
->name
[9] - '0';
1546 else if (strcmp (oo
->name
, "use_params") == 0)
1548 else if (strcmp (oo
->name
, "desc") == 0)
1550 else if (strcmp (oo
->name
, "nested_ptr") == 0)
1551 nested_ptr_d
= (const struct nested_ptr_data
*) oo
->info
;
1552 else if (strcmp (oo
->name
, "dot") == 0)
1554 else if (strcmp (oo
->name
, "tag") == 0)
1556 else if (strcmp (oo
->name
, "special") == 0)
1558 else if (strcmp (oo
->name
, "skip") == 0)
1560 else if (strcmp (oo
->name
, "default") == 0)
1562 else if (strcmp (oo
->name
, "descbits") == 0)
1564 else if (strcmp (oo
->name
, "param_is") == 0)
1566 else if (strncmp (oo
->name
, "param", 5) == 0
1567 && ISDIGIT (oo
->name
[5])
1568 && strcmp (oo
->name
+ 6, "_is") == 0)
1570 else if (strcmp (oo
->name
, "chain_next") == 0)
1572 else if (strcmp (oo
->name
, "chain_prev") == 0)
1574 else if (strcmp (oo
->name
, "reorder") == 0)
1577 error_at_line (d
->line
, "unknown option `%s'\n", oo
->name
);
1584 int pointer_p
= t
->kind
== TYPE_POINTER
;
1588 if (! UNION_OR_STRUCT_P (t
))
1589 error_at_line (d
->line
, "`use_params' option on unimplemented type");
1591 t
= find_param_structure (t
, d
->param
);
1593 t
= create_pointer (t
);
1596 if (use_param_num
!= -1)
1598 if (d
->param
!= NULL
&& d
->param
[use_param_num
] != NULL
)
1600 type_p nt
= d
->param
[use_param_num
];
1602 if (t
->kind
== TYPE_ARRAY
)
1603 nt
= create_array (nt
, t
->u
.a
.len
);
1604 else if (length
!= NULL
&& t
->kind
== TYPE_POINTER
)
1605 nt
= create_pointer (nt
);
1606 d
->needs_cast_p
= (t
->kind
!= TYPE_POINTER
1607 && (nt
->kind
== TYPE_POINTER
1608 || nt
->kind
== TYPE_STRING
));
1612 error_at_line (d
->line
, "no parameter defined for `%s'",
1617 && (t
->kind
!= TYPE_POINTER
|| ! UNION_OR_STRUCT_P (t
->u
.p
)))
1619 error_at_line (d
->line
,
1620 "field `%s' has invalid option `maybe_undef_p'\n",
1629 d
->process_field (t
, d
);
1635 && t
->u
.p
->u
.s
.line
.file
== NULL
)
1637 oprintf (d
->of
, "%*sgcc_assert (!%s);\n", d
->indent
, "", d
->val
);
1643 if (! UNION_OR_STRUCT_P (t
->u
.p
)
1644 && t
->u
.p
->kind
!= TYPE_PARAM_STRUCT
)
1646 error_at_line (d
->line
,
1647 "field `%s' is pointer to unimplemented type",
1654 const char *oldprevval2
= d
->prev_val
[2];
1656 if (! UNION_OR_STRUCT_P (nested_ptr_d
->type
))
1658 error_at_line (d
->line
,
1659 "field `%s' has invalid "
1660 "option `nested_ptr'\n",
1665 d
->prev_val
[2] = d
->val
;
1666 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1668 d
->val
= xasprintf ("x%d", d
->counter
++);
1669 oprintf (d
->of
, "%*s%s %s * %s%s =\n", d
->indent
, "",
1670 (nested_ptr_d
->type
->kind
== TYPE_UNION
1671 ? "union" : "struct"),
1672 nested_ptr_d
->type
->u
.s
.tag
,
1673 d
->fn_wants_lvalue
? "" : "const ",
1675 oprintf (d
->of
, "%*s", d
->indent
+ 2, "");
1676 output_escaped_param (d
, nested_ptr_d
->convert_from
,
1678 oprintf (d
->of
, ";\n");
1680 d
->process_field (nested_ptr_d
->type
, d
);
1682 if (d
->fn_wants_lvalue
)
1684 oprintf (d
->of
, "%*s%s = ", d
->indent
, "",
1686 d
->prev_val
[2] = d
->val
;
1687 output_escaped_param (d
, nested_ptr_d
->convert_to
,
1689 oprintf (d
->of
, ";\n");
1693 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1694 d
->val
= d
->prev_val
[2];
1695 d
->prev_val
[2] = oldprevval2
;
1698 d
->process_field (t
->u
.p
, d
);
1702 int loopcounter
= d
->counter
++;
1703 const char *oldval
= d
->val
;
1704 const char *oldprevval3
= d
->prev_val
[3];
1707 oprintf (d
->of
, "%*sif (%s != NULL) {\n", d
->indent
, "", d
->val
);
1709 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1710 oprintf (d
->of
, "%*sfor (i%d = 0; i%d != (size_t)(", d
->indent
, "",
1711 loopcounter
, loopcounter
);
1712 output_escaped_param (d
, length
, "length");
1713 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1715 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1717 d
->prev_val
[3] = oldval
;
1718 walk_type (t
->u
.p
, d
);
1721 d
->prev_val
[3] = oldprevval3
;
1724 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1725 d
->process_field(t
, d
);
1727 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1734 int loopcounter
= d
->counter
++;
1735 const char *oldval
= d
->val
;
1738 /* If it's an array of scalars, we optimize by not generating
1740 if (t
->u
.a
.p
->kind
== TYPE_SCALAR
)
1743 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1745 oprintf (d
->of
, "%*ssize_t i%d;\n", d
->indent
, "", loopcounter
);
1746 oprintf (d
->of
, "%*sfor (i%d = 0; i%d != (size_t)(", d
->indent
, "",
1747 loopcounter
, loopcounter
);
1749 output_escaped_param (d
, length
, "length");
1751 oprintf (d
->of
, "%s", t
->u
.a
.len
);
1752 oprintf (d
->of
, "); i%d++) {\n", loopcounter
);
1754 d
->val
= newval
= xasprintf ("%s[i%d]", oldval
, loopcounter
);
1756 walk_type (t
->u
.a
.p
, d
);
1761 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1763 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1771 const char *oldval
= d
->val
;
1772 const char *oldprevval1
= d
->prev_val
[1];
1773 const char *oldprevval2
= d
->prev_val
[2];
1774 const int union_p
= t
->kind
== TYPE_UNION
;
1775 int seen_default_p
= 0;
1778 if (! t
->u
.s
.line
.file
)
1779 error_at_line (d
->line
, "incomplete structure `%s'", t
->u
.s
.tag
);
1781 if ((d
->bitmap
& t
->u
.s
.bitmap
) != d
->bitmap
)
1783 error_at_line (d
->line
,
1784 "structure `%s' defined for mismatching languages",
1786 error_at_line (&t
->u
.s
.line
, "one structure defined here");
1789 /* Some things may also be defined in the structure's options. */
1790 for (o
= t
->u
.s
.opt
; o
; o
= o
->next
)
1791 if (! desc
&& strcmp (o
->name
, "desc") == 0)
1794 d
->prev_val
[2] = oldval
;
1795 d
->prev_val
[1] = oldprevval2
;
1800 error_at_line (d
->line
, "missing `desc' option for union `%s'",
1804 oprintf (d
->of
, "%*sswitch (", d
->indent
, "");
1805 output_escaped_param (d
, desc
, "desc");
1806 oprintf (d
->of
, ")\n");
1808 oprintf (d
->of
, "%*s{\n", d
->indent
, "");
1810 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
1813 const char *dot
= ".";
1814 const char *tagid
= NULL
;
1817 int use_param_p
= 0;
1820 d
->reorder_fn
= NULL
;
1821 for (oo
= f
->opt
; oo
; oo
= oo
->next
)
1822 if (strcmp (oo
->name
, "dot") == 0)
1824 else if (strcmp (oo
->name
, "tag") == 0)
1826 else if (strcmp (oo
->name
, "skip") == 0)
1828 else if (strcmp (oo
->name
, "default") == 0)
1830 else if (strcmp (oo
->name
, "reorder") == 0)
1831 d
->reorder_fn
= oo
->info
;
1832 else if (strncmp (oo
->name
, "use_param", 9) == 0
1833 && (oo
->name
[9] == '\0' || ISDIGIT (oo
->name
[9])))
1839 if (union_p
&& tagid
)
1841 oprintf (d
->of
, "%*scase %s:\n", d
->indent
, "", tagid
);
1844 else if (union_p
&& default_p
)
1846 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1850 else if (! union_p
&& (default_p
|| tagid
))
1851 error_at_line (d
->line
,
1852 "can't use `%s' outside a union on field `%s'",
1853 default_p
? "default" : "tag", f
->name
);
1854 else if (union_p
&& ! (default_p
|| tagid
)
1855 && f
->type
->kind
== TYPE_SCALAR
)
1858 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1859 d
->line
->file
, d
->line
->line
, f
->name
);
1862 else if (union_p
&& ! (default_p
|| tagid
))
1863 error_at_line (d
->line
,
1864 "field `%s' is missing `tag' or `default' option",
1868 d
->val
= newval
= xasprintf ("%s%s%s", oldval
, dot
, f
->name
);
1870 d
->used_length
= false;
1872 if (union_p
&& use_param_p
&& d
->param
== NULL
)
1873 oprintf (d
->of
, "%*sgcc_unreachable ();\n", d
->indent
, "");
1875 walk_type (f
->type
, d
);
1881 oprintf (d
->of
, "%*sbreak;\n", d
->indent
, "");
1885 d
->reorder_fn
= NULL
;
1888 d
->prev_val
[1] = oldprevval1
;
1889 d
->prev_val
[2] = oldprevval2
;
1891 if (union_p
&& ! seen_default_p
)
1893 oprintf (d
->of
, "%*sdefault:\n", d
->indent
, "");
1894 oprintf (d
->of
, "%*s break;\n", d
->indent
, "");
1898 oprintf (d
->of
, "%*s}\n", d
->indent
, "");
1904 case TYPE_LANG_STRUCT
:
1907 for (nt
= t
->u
.s
.lang_struct
; nt
; nt
= nt
->next
)
1908 if ((d
->bitmap
& nt
->u
.s
.bitmap
) == d
->bitmap
)
1911 error_at_line (d
->line
, "structure `%s' differs between languages",
1918 case TYPE_PARAM_STRUCT
:
1920 type_p
*oldparam
= d
->param
;
1922 d
->param
= t
->u
.param_struct
.param
;
1923 walk_type (t
->u
.param_struct
.stru
, d
);
1924 d
->param
= oldparam
;
1933 /* process_field routine for marking routines. */
1936 write_types_process_field (type_p f
, const struct walk_type_data
*d
)
1938 const struct write_types_data
*wtd
;
1939 const char *cast
= d
->needs_cast_p
? "(void *)" : "";
1940 wtd
= (const struct write_types_data
*) d
->cookie
;
1945 oprintf (d
->of
, "%*s%s (%s%s", d
->indent
, "",
1946 wtd
->subfield_marker_routine
, cast
, d
->val
);
1947 if (wtd
->param_prefix
)
1949 oprintf (d
->of
, ", %s", d
->prev_val
[3]);
1952 oprintf (d
->of
, ", gt_%s_", wtd
->param_prefix
);
1953 output_mangled_typename (d
->of
, d
->orig_s
);
1956 oprintf (d
->of
, ", gt_%sa_%s", wtd
->param_prefix
, d
->prev_val
[0]);
1958 if (f
->u
.p
->kind
== TYPE_PARAM_STRUCT
1959 && f
->u
.p
->u
.s
.line
.file
!= NULL
)
1961 oprintf (d
->of
, ", gt_e_");
1962 output_mangled_typename (d
->of
, f
);
1964 else if (UNION_OR_STRUCT_P (f
)
1965 && f
->u
.p
->u
.s
.line
.file
!= NULL
)
1967 oprintf (d
->of
, ", gt_ggc_e_");
1968 output_mangled_typename (d
->of
, f
);
1971 oprintf (d
->of
, ", gt_types_enum_last");
1973 oprintf (d
->of
, ");\n");
1974 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1975 oprintf (d
->of
, "%*s%s (%s%s, %s, %s);\n", d
->indent
, "",
1976 wtd
->reorder_note_routine
, cast
, d
->val
,
1977 d
->prev_val
[3], d
->reorder_fn
);
1981 if (wtd
->param_prefix
== NULL
)
1986 case TYPE_LANG_STRUCT
:
1987 case TYPE_PARAM_STRUCT
:
1988 oprintf (d
->of
, "%*sgt_%s_", d
->indent
, "", wtd
->prefix
);
1989 output_mangled_typename (d
->of
, f
);
1990 oprintf (d
->of
, " (%s%s);\n", cast
, d
->val
);
1991 if (d
->reorder_fn
&& wtd
->reorder_note_routine
)
1992 oprintf (d
->of
, "%*s%s (%s%s, %s%s, %s);\n", d
->indent
, "",
1993 wtd
->reorder_note_routine
, cast
, d
->val
, cast
, d
->val
,
2005 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
2008 output_type_enum (outf_p of
, type_p s
)
2010 if (s
->kind
== TYPE_PARAM_STRUCT
&& s
->u
.s
.line
.file
!= NULL
)
2012 oprintf (of
, ", gt_e_");
2013 output_mangled_typename (of
, s
);
2015 else if (UNION_OR_STRUCT_P (s
) && s
->u
.s
.line
.file
!= NULL
)
2017 oprintf (of
, ", gt_ggc_e_");
2018 output_mangled_typename (of
, s
);
2021 oprintf (of
, ", gt_types_enum_last");
2024 /* For S, a structure that's part of ORIG_S, and using parameters
2025 PARAM, write out a routine that:
2026 - Takes a parameter, a void * but actually of type *S
2027 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2028 field of S or its substructures and (in some cases) things
2029 that are pointed to by S.
2033 write_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
,
2034 const struct write_types_data
*wtd
)
2036 const char *fn
= s
->u
.s
.line
.file
;
2038 const char *chain_next
= NULL
;
2039 const char *chain_prev
= NULL
;
2041 struct walk_type_data d
;
2043 /* This is a hack, and not the good kind either. */
2044 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
2045 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
2046 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
2047 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2049 memset (&d
, 0, sizeof (d
));
2050 d
.of
= get_output_file_with_visibility (fn
);
2052 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2053 if (strcmp (opt
->name
, "chain_next") == 0)
2054 chain_next
= opt
->info
;
2055 else if (strcmp (opt
->name
, "chain_prev") == 0)
2056 chain_prev
= opt
->info
;
2058 if (chain_prev
!= NULL
&& chain_next
== NULL
)
2059 error_at_line (&s
->u
.s
.line
, "chain_prev without chain_next");
2061 d
.process_field
= write_types_process_field
;
2065 d
.line
= &s
->u
.s
.line
;
2066 d
.bitmap
= s
->u
.s
.bitmap
;
2068 d
.prev_val
[0] = "*x";
2069 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2070 d
.prev_val
[3] = "x";
2073 oprintf (d
.of
, "\n");
2074 oprintf (d
.of
, "void\n");
2076 oprintf (d
.of
, "gt_%sx_%s", wtd
->prefix
, orig_s
->u
.s
.tag
);
2079 oprintf (d
.of
, "gt_%s_", wtd
->prefix
);
2080 output_mangled_typename (d
.of
, orig_s
);
2082 oprintf (d
.of
, " (void *x_p)\n");
2083 oprintf (d
.of
, "{\n");
2084 oprintf (d
.of
, " %s %s * %sx = (%s %s *)x_p;\n",
2085 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2086 chain_next
== NULL
? "const " : "",
2087 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2088 if (chain_next
!= NULL
)
2089 oprintf (d
.of
, " %s %s * xlimit = x;\n",
2090 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2091 if (chain_next
== NULL
)
2093 oprintf (d
.of
, " if (%s (x", wtd
->marker_routine
);
2094 if (wtd
->param_prefix
)
2096 oprintf (d
.of
, ", x, gt_%s_", wtd
->param_prefix
);
2097 output_mangled_typename (d
.of
, orig_s
);
2098 output_type_enum (d
.of
, orig_s
);
2100 oprintf (d
.of
, "))\n");
2104 oprintf (d
.of
, " while (%s (xlimit", wtd
->marker_routine
);
2105 if (wtd
->param_prefix
)
2107 oprintf (d
.of
, ", xlimit, gt_%s_", wtd
->param_prefix
);
2108 output_mangled_typename (d
.of
, orig_s
);
2109 output_type_enum (d
.of
, orig_s
);
2111 oprintf (d
.of
, "))\n");
2112 oprintf (d
.of
, " xlimit = (");
2113 d
.prev_val
[2] = "*xlimit";
2114 output_escaped_param (&d
, chain_next
, "chain_next");
2115 oprintf (d
.of
, ");\n");
2116 if (chain_prev
!= NULL
)
2118 oprintf (d
.of
, " if (x != xlimit)\n");
2119 oprintf (d
.of
, " for (;;)\n");
2120 oprintf (d
.of
, " {\n");
2121 oprintf (d
.of
, " %s %s * const xprev = (",
2122 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2124 d
.prev_val
[2] = "*x";
2125 output_escaped_param (&d
, chain_prev
, "chain_prev");
2126 oprintf (d
.of
, ");\n");
2127 oprintf (d
.of
, " if (xprev == NULL) break;\n");
2128 oprintf (d
.of
, " x = xprev;\n");
2129 oprintf (d
.of
, " (void) %s (xprev",
2130 wtd
->marker_routine
);
2131 if (wtd
->param_prefix
)
2133 oprintf (d
.of
, ", xprev, gt_%s_", wtd
->param_prefix
);
2134 output_mangled_typename (d
.of
, orig_s
);
2135 output_type_enum (d
.of
, orig_s
);
2137 oprintf (d
.of
, ");\n");
2138 oprintf (d
.of
, " }\n");
2140 oprintf (d
.of
, " while (x != xlimit)\n");
2142 oprintf (d
.of
, " {\n");
2144 d
.prev_val
[2] = "*x";
2148 if (chain_next
!= NULL
)
2150 oprintf (d
.of
, " x = (");
2151 output_escaped_param (&d
, chain_next
, "chain_next");
2152 oprintf (d
.of
, ");\n");
2155 oprintf (d
.of
, " }\n");
2156 oprintf (d
.of
, "}\n");
2159 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2162 write_types (type_p structures
, type_p param_structs
,
2163 const struct write_types_data
*wtd
)
2167 oprintf (header_file
, "\n/* %s*/\n", wtd
->comment
);
2168 for (s
= structures
; s
; s
= s
->next
)
2169 if (s
->gc_used
== GC_POINTED_TO
2170 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2174 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2175 && s
->u
.s
.line
.file
== NULL
)
2178 oprintf (header_file
, "#define gt_%s_", wtd
->prefix
);
2179 output_mangled_typename (header_file
, s
);
2180 oprintf (header_file
, "(X) do { \\\n");
2181 oprintf (header_file
,
2182 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd
->prefix
,
2184 oprintf (header_file
,
2187 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2188 if (strcmp (opt
->name
, "ptr_alias") == 0)
2190 type_p t
= (type_p
) opt
->info
;
2191 if (t
->kind
== TYPE_STRUCT
2192 || t
->kind
== TYPE_UNION
2193 || t
->kind
== TYPE_LANG_STRUCT
)
2194 oprintf (header_file
,
2195 "#define gt_%sx_%s gt_%sx_%s\n",
2196 wtd
->prefix
, s
->u
.s
.tag
, wtd
->prefix
, t
->u
.s
.tag
);
2198 error_at_line (&s
->u
.s
.line
,
2199 "structure alias is not a structure");
2205 /* Declare the marker procedure only once. */
2206 oprintf (header_file
,
2207 "extern void gt_%sx_%s (void *);\n",
2208 wtd
->prefix
, s
->u
.s
.tag
);
2210 if (s
->u
.s
.line
.file
== NULL
)
2212 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2217 if (s
->kind
== TYPE_LANG_STRUCT
)
2220 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2221 write_func_for_structure (s
, ss
, NULL
, wtd
);
2224 write_func_for_structure (s
, s
, NULL
, wtd
);
2227 for (s
= param_structs
; s
; s
= s
->next
)
2228 if (s
->gc_used
== GC_POINTED_TO
)
2230 type_p
* param
= s
->u
.param_struct
.param
;
2231 type_p stru
= s
->u
.param_struct
.stru
;
2233 /* Declare the marker procedure. */
2234 oprintf (header_file
, "extern void gt_%s_", wtd
->prefix
);
2235 output_mangled_typename (header_file
, s
);
2236 oprintf (header_file
, " (void *);\n");
2238 if (stru
->u
.s
.line
.file
== NULL
)
2240 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2245 if (stru
->kind
== TYPE_LANG_STRUCT
)
2248 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2249 write_func_for_structure (s
, ss
, param
, wtd
);
2252 write_func_for_structure (s
, stru
, param
, wtd
);
2256 static const struct write_types_data ggc_wtd
=
2258 "ggc_m", NULL
, "ggc_mark", "ggc_test_and_set_mark", NULL
,
2259 "GC marker procedures. "
2262 static const struct write_types_data pch_wtd
=
2264 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2265 "gt_pch_note_reorder",
2266 "PCH type-walking procedures. "
2269 /* Write out the local pointer-walking routines. */
2271 /* process_field routine for local pointer-walking. */
2274 write_types_local_process_field (type_p f
, const struct walk_type_data
*d
)
2281 case TYPE_LANG_STRUCT
:
2282 case TYPE_PARAM_STRUCT
:
2284 oprintf (d
->of
, "%*sif ((void *)(%s) == this_obj)\n", d
->indent
, "",
2286 oprintf (d
->of
, "%*s op (&(%s), cookie);\n", d
->indent
, "", d
->val
);
2297 /* For S, a structure that's part of ORIG_S, and using parameters
2298 PARAM, write out a routine that:
2299 - Is of type gt_note_pointers
2300 - Calls PROCESS_FIELD on each field of S or its substructures.
2304 write_local_func_for_structure (type_p orig_s
, type_p s
, type_p
*param
)
2306 const char *fn
= s
->u
.s
.line
.file
;
2308 struct walk_type_data d
;
2310 /* This is a hack, and not the good kind either. */
2311 for (i
= NUM_PARAM
- 1; i
>= 0; i
--)
2312 if (param
&& param
[i
] && param
[i
]->kind
== TYPE_POINTER
2313 && UNION_OR_STRUCT_P (param
[i
]->u
.p
))
2314 fn
= param
[i
]->u
.p
->u
.s
.line
.file
;
2316 memset (&d
, 0, sizeof (d
));
2317 d
.of
= get_output_file_with_visibility (fn
);
2319 d
.process_field
= write_types_local_process_field
;
2321 d
.line
= &s
->u
.s
.line
;
2322 d
.bitmap
= s
->u
.s
.bitmap
;
2324 d
.prev_val
[0] = d
.prev_val
[2] = "*x";
2325 d
.prev_val
[1] = "not valid postage"; /* Guarantee an error. */
2326 d
.prev_val
[3] = "x";
2328 d
.fn_wants_lvalue
= true;
2330 oprintf (d
.of
, "\n");
2331 oprintf (d
.of
, "void\n");
2332 oprintf (d
.of
, "gt_pch_p_");
2333 output_mangled_typename (d
.of
, orig_s
);
2334 oprintf (d
.of
, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2336 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2337 "\tATTRIBUTE_UNUSED void *cookie)\n");
2338 oprintf (d
.of
, "{\n");
2339 oprintf (d
.of
, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2340 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
2341 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
2344 oprintf (d
.of
, "}\n");
2347 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2350 write_local (type_p structures
, type_p param_structs
)
2354 oprintf (header_file
, "\n/* Local pointer-walking routines. */\n");
2355 for (s
= structures
; s
; s
= s
->next
)
2356 if (s
->gc_used
== GC_POINTED_TO
2357 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2361 if (s
->u
.s
.line
.file
== NULL
)
2364 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
2365 if (strcmp (opt
->name
, "ptr_alias") == 0)
2367 type_p t
= (type_p
) opt
->info
;
2368 if (t
->kind
== TYPE_STRUCT
2369 || t
->kind
== TYPE_UNION
2370 || t
->kind
== TYPE_LANG_STRUCT
)
2372 oprintf (header_file
, "#define gt_pch_p_");
2373 output_mangled_typename (header_file
, s
);
2374 oprintf (header_file
, " gt_pch_p_");
2375 output_mangled_typename (header_file
, t
);
2376 oprintf (header_file
, "\n");
2379 error_at_line (&s
->u
.s
.line
,
2380 "structure alias is not a structure");
2386 /* Declare the marker procedure only once. */
2387 oprintf (header_file
, "extern void gt_pch_p_");
2388 output_mangled_typename (header_file
, s
);
2389 oprintf (header_file
,
2390 "\n (void *, void *, gt_pointer_operator, void *);\n");
2392 if (s
->kind
== TYPE_LANG_STRUCT
)
2395 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2396 write_local_func_for_structure (s
, ss
, NULL
);
2399 write_local_func_for_structure (s
, s
, NULL
);
2402 for (s
= param_structs
; s
; s
= s
->next
)
2403 if (s
->gc_used
== GC_POINTED_TO
)
2405 type_p
* param
= s
->u
.param_struct
.param
;
2406 type_p stru
= s
->u
.param_struct
.stru
;
2408 /* Declare the marker procedure. */
2409 oprintf (header_file
, "extern void gt_pch_p_");
2410 output_mangled_typename (header_file
, s
);
2411 oprintf (header_file
,
2412 "\n (void *, void *, gt_pointer_operator, void *);\n");
2414 if (stru
->u
.s
.line
.file
== NULL
)
2416 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
2421 if (stru
->kind
== TYPE_LANG_STRUCT
)
2424 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
2425 write_local_func_for_structure (s
, ss
, param
);
2428 write_local_func_for_structure (s
, stru
, param
);
2432 /* Write out the 'enum' definition for gt_types_enum. */
2435 write_enum_defn (type_p structures
, type_p param_structs
)
2439 oprintf (header_file
, "\n/* Enumeration of types known. */\n");
2440 oprintf (header_file
, "enum gt_types_enum {\n");
2441 for (s
= structures
; s
; s
= s
->next
)
2442 if (s
->gc_used
== GC_POINTED_TO
2443 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
2445 if (s
->gc_used
== GC_MAYBE_POINTED_TO
2446 && s
->u
.s
.line
.file
== NULL
)
2449 oprintf (header_file
, " gt_ggc_e_");
2450 output_mangled_typename (header_file
, s
);
2451 oprintf (header_file
, ", \n");
2453 for (s
= param_structs
; s
; s
= s
->next
)
2454 if (s
->gc_used
== GC_POINTED_TO
)
2456 oprintf (header_file
, " gt_e_");
2457 output_mangled_typename (header_file
, s
);
2458 oprintf (header_file
, ", \n");
2460 oprintf (header_file
, " gt_types_enum_last\n");
2461 oprintf (header_file
, "};\n");
2464 /* Might T contain any non-pointer elements? */
2467 contains_scalar_p (type_p t
)
2475 return contains_scalar_p (t
->u
.a
.p
);
2477 /* Could also check for structures that have no non-pointer
2478 fields, but there aren't enough of those to worry about. */
2483 /* Mangle FN and print it to F. */
2486 put_mangled_filename (outf_p f
, const char *fn
)
2488 const char *name
= get_output_file_name (fn
);
2489 for (; *name
!= 0; name
++)
2490 if (ISALNUM (*name
))
2491 oprintf (f
, "%c", *name
);
2493 oprintf (f
, "%c", '_');
2496 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2497 LASTNAME, and NAME are all strings to insert in various places in
2498 the resulting code. */
2501 finish_root_table (struct flist
*flp
, const char *pfx
, const char *lastname
,
2502 const char *tname
, const char *name
)
2506 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2507 if (fli2
->started_p
)
2509 oprintf (fli2
->f
, " %s\n", lastname
);
2510 oprintf (fli2
->f
, "};\n\n");
2513 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2514 if (fli2
->started_p
)
2516 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2519 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2522 oprintf (base_files
[fnum
],
2523 "extern const struct %s gt_%s_",
2525 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2526 oprintf (base_files
[fnum
], "[];\n");
2532 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2533 oprintf (base_files
[fnum
],
2534 "const struct %s * const %s[] = {\n",
2539 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
2540 if (fli2
->started_p
)
2542 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
2545 fli2
->started_p
= 0;
2547 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
2550 oprintf (base_files
[fnum
], " gt_%s_", pfx
);
2551 put_mangled_filename (base_files
[fnum
], fli2
->name
);
2552 oprintf (base_files
[fnum
], ",\n");
2558 for (fnum
= 0; fnum
< NUM_BASE_FILES
; fnum
++)
2560 oprintf (base_files
[fnum
], " NULL\n");
2561 oprintf (base_files
[fnum
], "};\n");
2566 /* Write out to F the table entry and any marker routines needed to
2567 mark NAME as TYPE. The original variable is V, at LINE.
2568 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2569 is nonzero iff we are building the root table for hash table caches. */
2572 write_root (outf_p f
, pair_p v
, type_p type
, const char *name
, int has_length
,
2573 struct fileloc
*line
, const char *if_marked
)
2580 for (fld
= type
->u
.s
.fields
; fld
; fld
= fld
->next
)
2583 const char *desc
= NULL
;
2586 for (o
= fld
->opt
; o
; o
= o
->next
)
2587 if (strcmp (o
->name
, "skip") == 0)
2589 else if (strcmp (o
->name
, "desc") == 0)
2592 error_at_line (line
,
2593 "field `%s' of global `%s' has unknown option `%s'",
2594 fld
->name
, name
, o
->name
);
2598 else if (desc
&& fld
->type
->kind
== TYPE_UNION
)
2600 pair_p validf
= NULL
;
2603 for (ufld
= fld
->type
->u
.s
.fields
; ufld
; ufld
= ufld
->next
)
2605 const char *tag
= NULL
;
2608 for (oo
= ufld
->opt
; oo
; oo
= oo
->next
)
2609 if (strcmp (oo
->name
, "tag") == 0)
2611 if (tag
== NULL
|| strcmp (tag
, desc
) != 0)
2614 error_at_line (line
,
2615 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2616 name
, fld
->name
, validf
->name
,
2617 name
, fld
->name
, ufld
->name
,
2624 newname
= xasprintf ("%s.%s.%s",
2625 name
, fld
->name
, validf
->name
);
2626 write_root (f
, v
, validf
->type
, newname
, 0, line
,
2632 error_at_line (line
,
2633 "global `%s.%s' has `desc' option but is not union",
2638 newname
= xasprintf ("%s.%s", name
, fld
->name
);
2639 write_root (f
, v
, fld
->type
, newname
, 0, line
, if_marked
);
2649 newname
= xasprintf ("%s[0]", name
);
2650 write_root (f
, v
, type
->u
.a
.p
, newname
, has_length
, line
, if_marked
);
2659 oprintf (f
, " {\n");
2660 oprintf (f
, " &%s,\n", name
);
2663 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2665 oprintf (f
, " * (%s)", ap
->u
.a
.len
);
2666 else if (ap
== v
->type
)
2667 oprintf (f
, " * ARRAY_SIZE (%s)", v
->name
);
2669 oprintf (f
, " sizeof (%s", v
->name
);
2670 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
2672 oprintf (f
, "),\n");
2676 if (! has_length
&& UNION_OR_STRUCT_P (tp
))
2678 oprintf (f
, " >_ggc_mx_%s,\n", tp
->u
.s
.tag
);
2679 oprintf (f
, " >_pch_nx_%s", tp
->u
.s
.tag
);
2681 else if (! has_length
&& tp
->kind
== TYPE_PARAM_STRUCT
)
2683 oprintf (f
, " >_ggc_m_");
2684 output_mangled_typename (f
, tp
);
2685 oprintf (f
, ",\n >_pch_n_");
2686 output_mangled_typename (f
, tp
);
2689 && (tp
->kind
== TYPE_POINTER
|| UNION_OR_STRUCT_P (tp
)))
2691 oprintf (f
, " >_ggc_ma_%s,\n", name
);
2692 oprintf (f
, " >_pch_na_%s", name
);
2696 error_at_line (line
,
2697 "global `%s' is pointer to unimplemented type",
2701 oprintf (f
, ",\n &%s", if_marked
);
2702 oprintf (f
, "\n },\n");
2708 oprintf (f
, " {\n");
2709 oprintf (f
, " &%s,\n", name
);
2710 oprintf (f
, " 1, \n");
2711 oprintf (f
, " sizeof (%s),\n", v
->name
);
2712 oprintf (f
, " >_ggc_m_S,\n");
2713 oprintf (f
, " (gt_pointer_walker) >_pch_n_S\n");
2714 oprintf (f
, " },\n");
2722 error_at_line (line
,
2723 "global `%s' is unimplemented type",
2728 /* This generates a routine to walk an array. */
2731 write_array (outf_p f
, pair_p v
, const struct write_types_data
*wtd
)
2733 struct walk_type_data d
;
2736 memset (&d
, 0, sizeof (d
));
2742 d
.bitmap
= get_base_file_bitmap (v
->line
.file
);
2745 d
.prev_val
[3] = prevval3
= xasprintf ("&%s", v
->name
);
2747 if (wtd
->param_prefix
)
2749 oprintf (f
, "static void gt_%sa_%s\n", wtd
->param_prefix
, v
->name
);
2751 " (void *, void *, gt_pointer_operator, void *);\n");
2752 oprintf (f
, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2753 wtd
->param_prefix
, v
->name
);
2755 " ATTRIBUTE_UNUSED void *x_p,\n"
2756 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2757 " ATTRIBUTE_UNUSED void * cookie)\n");
2758 oprintf (d
.of
, "{\n");
2759 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2760 d
.process_field
= write_types_local_process_field
;
2761 walk_type (v
->type
, &d
);
2762 oprintf (f
, "}\n\n");
2766 oprintf (f
, "static void gt_%sa_%s (void *);\n",
2767 wtd
->prefix
, v
->name
);
2768 oprintf (f
, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2769 wtd
->prefix
, v
->name
);
2771 d
.prev_val
[0] = d
.prev_val
[1] = d
.prev_val
[2] = d
.val
= v
->name
;
2772 d
.process_field
= write_types_process_field
;
2773 walk_type (v
->type
, &d
);
2775 oprintf (f
, "}\n\n");
2778 /* Output a table describing the locations and types of VARIABLES. */
2781 write_roots (pair_p variables
)
2784 struct flist
*flp
= NULL
;
2786 for (v
= variables
; v
; v
= v
->next
)
2788 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2790 const char *length
= NULL
;
2791 int deletable_p
= 0;
2794 for (o
= v
->opt
; o
; o
= o
->next
)
2795 if (strcmp (o
->name
, "length") == 0)
2797 else if (strcmp (o
->name
, "deletable") == 0)
2799 else if (strcmp (o
->name
, "param_is") == 0)
2801 else if (strncmp (o
->name
, "param", 5) == 0
2802 && ISDIGIT (o
->name
[5])
2803 && strcmp (o
->name
+ 6, "_is") == 0)
2805 else if (strcmp (o
->name
, "if_marked") == 0)
2808 error_at_line (&v
->line
,
2809 "global `%s' has unknown option `%s'",
2812 for (fli
= flp
; fli
; fli
= fli
->next
)
2817 fli
= XNEW (struct flist
);
2821 fli
->name
= v
->line
.file
;
2824 oprintf (f
, "\n/* GC roots. */\n\n");
2829 && v
->type
->kind
== TYPE_POINTER
2830 && (v
->type
->u
.p
->kind
== TYPE_POINTER
2831 || v
->type
->u
.p
->kind
== TYPE_STRUCT
))
2833 write_array (f
, v
, &ggc_wtd
);
2834 write_array (f
, v
, &pch_wtd
);
2838 for (v
= variables
; v
; v
= v
->next
)
2840 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2846 for (o
= v
->opt
; o
; o
= o
->next
)
2847 if (strcmp (o
->name
, "length") == 0)
2849 else if (strcmp (o
->name
, "deletable") == 0
2850 || strcmp (o
->name
, "if_marked") == 0)
2856 for (fli
= flp
; fli
; fli
= fli
->next
)
2859 if (! fli
->started_p
)
2863 oprintf (f
, "const struct ggc_root_tab gt_ggc_r_");
2864 put_mangled_filename (f
, v
->line
.file
);
2865 oprintf (f
, "[] = {\n");
2868 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2871 finish_root_table (flp
, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2874 for (v
= variables
; v
; v
= v
->next
)
2876 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2881 for (o
= v
->opt
; o
; o
= o
->next
)
2882 if (strcmp (o
->name
, "deletable") == 0)
2884 else if (strcmp (o
->name
, "if_marked") == 0)
2890 for (fli
= flp
; fli
; fli
= fli
->next
)
2893 if (! fli
->started_p
)
2897 oprintf (f
, "const struct ggc_root_tab gt_ggc_rd_");
2898 put_mangled_filename (f
, v
->line
.file
);
2899 oprintf (f
, "[] = {\n");
2902 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2906 finish_root_table (flp
, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2907 "gt_ggc_deletable_rtab");
2909 for (v
= variables
; v
; v
= v
->next
)
2911 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2913 const char *if_marked
= NULL
;
2917 for (o
= v
->opt
; o
; o
= o
->next
)
2918 if (strcmp (o
->name
, "length") == 0)
2920 else if (strcmp (o
->name
, "if_marked") == 0)
2921 if_marked
= o
->info
;
2923 if (if_marked
== NULL
)
2926 if (v
->type
->kind
!= TYPE_POINTER
2927 || v
->type
->u
.p
->kind
!= TYPE_PARAM_STRUCT
2928 || v
->type
->u
.p
->u
.param_struct
.stru
!= find_structure ("htab", 0))
2930 error_at_line (&v
->line
, "if_marked option used but not hash table");
2934 for (fli
= flp
; fli
; fli
= fli
->next
)
2937 if (! fli
->started_p
)
2941 oprintf (f
, "const struct ggc_cache_tab gt_ggc_rc_");
2942 put_mangled_filename (f
, v
->line
.file
);
2943 oprintf (f
, "[] = {\n");
2946 write_root (f
, v
, v
->type
->u
.p
->u
.param_struct
.param
[0],
2947 v
->name
, length_p
, &v
->line
, if_marked
);
2950 finish_root_table (flp
, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2951 "gt_ggc_cache_rtab");
2953 for (v
= variables
; v
; v
= v
->next
)
2955 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2958 int if_marked_p
= 0;
2961 for (o
= v
->opt
; o
; o
= o
->next
)
2962 if (strcmp (o
->name
, "length") == 0)
2964 else if (strcmp (o
->name
, "if_marked") == 0)
2970 for (fli
= flp
; fli
; fli
= fli
->next
)
2973 if (! fli
->started_p
)
2977 oprintf (f
, "const struct ggc_root_tab gt_pch_rc_");
2978 put_mangled_filename (f
, v
->line
.file
);
2979 oprintf (f
, "[] = {\n");
2982 write_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
2985 finish_root_table (flp
, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2986 "gt_pch_cache_rtab");
2988 for (v
= variables
; v
; v
= v
->next
)
2990 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
2995 for (o
= v
->opt
; o
; o
= o
->next
)
2996 if (strcmp (o
->name
, "deletable") == 0
2997 || strcmp (o
->name
, "if_marked") == 0)
3003 if (! contains_scalar_p (v
->type
))
3006 for (fli
= flp
; fli
; fli
= fli
->next
)
3009 if (! fli
->started_p
)
3013 oprintf (f
, "const struct ggc_root_tab gt_pch_rs_");
3014 put_mangled_filename (f
, v
->line
.file
);
3015 oprintf (f
, "[] = {\n");
3018 oprintf (f
, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3022 finish_root_table (flp
, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3023 "gt_pch_scalar_rtab");
3027 extern int main (int argc
, char **argv
);
3029 main(int ARG_UNUSED (argc
), char ** ARG_UNUSED (argv
))
3032 static struct fileloc pos
= { __FILE__
, __LINE__
};
3037 srcdir_len
= strlen (srcdir
);
3039 do_scalar_typedef ("CUMULATIVE_ARGS", &pos
);
3040 do_scalar_typedef ("REAL_VALUE_TYPE", &pos
);
3041 do_scalar_typedef ("double_int", &pos
);
3042 do_scalar_typedef ("uint8", &pos
);
3043 do_scalar_typedef ("jword", &pos
);
3044 do_scalar_typedef ("JCF_u2", &pos
);
3045 #ifdef USE_MAPPED_LOCATION
3046 do_scalar_typedef ("location_t", &pos
);
3047 do_scalar_typedef ("source_locus", &pos
);
3049 do_scalar_typedef ("void", &pos
);
3051 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos
)), &pos
);
3053 do_typedef ("HARD_REG_SET", create_array (
3054 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3057 for (i
= 0; i
< NUM_GT_FILES
; i
++)
3060 /* Omit if already seen. */
3061 for (j
= 0; j
< i
; j
++)
3063 if (!strcmp (all_files
[i
], all_files
[j
]))
3070 parse_file (all_files
[i
]);
3071 #ifndef USE_MAPPED_LOCATION
3072 /* temporary kludge - gengtype doesn't handle conditionals.
3073 Manually add source_locus *after* we've processed input.h. */
3075 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos
)), &pos
);
3082 set_gc_used (variables
);
3085 write_enum_defn (structures
, param_structs
);
3086 write_types (structures
, param_structs
, &ggc_wtd
);
3087 write_types (structures
, param_structs
, &pch_wtd
);
3088 write_local (structures
, param_structs
);
3089 write_roots (variables
);
3091 close_output_files ();
3093 return (hit_error
!= 0);