1 /* Process source files and output type information.
2 Copyright (C) 2002 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "coretypes.h"
28 /* Nonzero iff an error has occurred. */
29 static int hit_error = 0;
31 static void gen_rtx_next PARAMS ((void));
32 static void write_rtx_next PARAMS ((void));
33 static void open_base_files PARAMS ((void));
34 static void close_output_files PARAMS ((void));
36 /* Report an error at POS, printing MSG. */
39 error_at_line VPARAMS ((struct fileloc *pos, const char *msg, ...))
42 VA_FIXEDARG (ap, struct fileloc *, pos);
43 VA_FIXEDARG (ap, const char *, msg);
45 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
46 vfprintf (stderr, msg, ap);
53 /* vasprintf, but produces fatal message on out-of-memory. */
55 xvasprintf (result, format, args)
60 int ret = vasprintf (result, format, args);
61 if (*result == NULL || ret < 0)
63 fputs ("gengtype: out of memory", stderr);
69 /* Wrapper for xvasprintf. */
71 xasprintf VPARAMS ((const char *format, ...))
75 VA_FIXEDARG (ap, const char *, format);
76 xvasprintf (&result, format, ap);
81 /* The one and only TYPE_STRING. */
83 struct type string_type = {
84 TYPE_STRING, NULL, NULL, GC_USED
88 /* Lists of various things. */
90 static pair_p typedefs;
91 static type_p structures;
92 static type_p param_structs;
93 static pair_p variables;
95 static void do_scalar_typedef PARAMS ((const char *, struct fileloc *));
96 static type_p find_param_structure
97 PARAMS ((type_p t, type_p param[NUM_PARAM]));
98 static type_p adjust_field_tree_exp PARAMS ((type_p t, options_p opt));
99 static type_p adjust_field_rtx_def PARAMS ((type_p t, options_p opt));
101 /* Define S as a typedef to T at POS. */
104 do_typedef (s, t, pos)
111 for (p = typedefs; p != NULL; p = p->next)
112 if (strcmp (p->name, s) == 0)
116 error_at_line (pos, "type `%s' previously defined", s);
117 error_at_line (&p->line, "previously defined here");
122 p = xmalloc (sizeof (struct pair));
130 /* Define S as a typename of a scalar. */
133 do_scalar_typedef (s, pos)
137 do_typedef (s, create_scalar_type (s, strlen (s)), pos);
140 /* Return the type previously defined for S. Use POS to report errors. */
143 resolve_typedef (s, pos)
148 for (p = typedefs; p != NULL; p = p->next)
149 if (strcmp (p->name, s) == 0)
151 error_at_line (pos, "unidentified type `%s'", s);
152 return create_scalar_type ("char", 4);
155 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
156 at POS with fields FIELDS and options O. */
159 new_structure (name, isunion, pos, fields, o)
168 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
170 for (si = structures; si != NULL; si = si->next)
171 if (strcmp (name, si->u.s.tag) == 0
172 && UNION_P (si) == isunion)
175 if (si->kind == TYPE_LANG_STRUCT)
179 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
180 if (si->u.s.bitmap == bitmap)
183 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
186 si = xcalloc (1, sizeof (struct type));
187 memcpy (si, ls, sizeof (struct type));
188 ls->kind = TYPE_LANG_STRUCT;
189 ls->u.s.lang_struct = si;
190 ls->u.s.fields = NULL;
192 si->pointer_to = NULL;
193 si->u.s.lang_struct = ls;
198 if (ls != NULL && s == NULL)
200 s = xcalloc (1, sizeof (struct type));
201 s->next = ls->u.s.lang_struct;
202 ls->u.s.lang_struct = s;
203 s->u.s.lang_struct = ls;
210 s = xcalloc (1, sizeof (struct type));
211 s->next = structures;
215 if (s->u.s.line.file != NULL
216 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
218 error_at_line (pos, "duplicate structure definition");
219 error_at_line (&s->u.s.line, "previous definition here");
222 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
225 s->u.s.fields = fields;
227 s->u.s.bitmap = bitmap;
228 if (s->u.s.lang_struct)
229 s->u.s.lang_struct->u.s.bitmap |= bitmap;
232 /* Return the previously-defined structure with tag NAME (or a union
233 iff ISUNION is nonzero), or a new empty structure or union if none
234 was defined previously. */
237 find_structure (name, isunion)
243 for (s = structures; s != NULL; s = s->next)
244 if (strcmp (name, s->u.s.tag) == 0
245 && UNION_P (s) == isunion)
248 s = xcalloc (1, sizeof (struct type));
249 s->next = structures;
251 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
257 /* Return the previously-defined parameterized structure for structure
258 T and parameters PARAM, or a new parameterized empty structure or
259 union if none was defined previously. */
262 find_param_structure (t, param)
264 type_p param[NUM_PARAM];
268 for (res = param_structs; res; res = res->next)
269 if (res->u.param_struct.stru == t
270 && memcmp (res->u.param_struct.param, param,
271 sizeof (type_p) * NUM_PARAM) == 0)
275 res = xcalloc (1, sizeof (*res));
276 res->kind = TYPE_PARAM_STRUCT;
277 res->next = param_structs;
279 res->u.param_struct.stru = t;
280 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
285 /* Return a scalar type with name NAME. */
288 create_scalar_type (name, name_len)
292 type_p r = xcalloc (1, sizeof (struct type));
293 r->kind = TYPE_SCALAR;
294 r->u.sc = xmemdup (name, name_len, name_len + 1);
298 /* Return a pointer to T. */
306 type_p r = xcalloc (1, sizeof (struct type));
307 r->kind = TYPE_POINTER;
311 return t->pointer_to;
314 /* Return an array of length LEN. */
317 create_array (t, len)
323 v = xcalloc (1, sizeof (*v));
324 v->kind = TYPE_ARRAY;
330 /* Add a variable named S of type T with options O defined at POS,
334 note_variable (s, t, o, pos)
341 n = xmalloc (sizeof (*n));
351 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
357 /* We really don't care how long a CONST_DOUBLE is. */
358 #define CONST_DOUBLE_FORMAT "ww"
359 static const char * const rtx_format[NUM_RTX_CODE] = {
360 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
365 static int rtx_next[NUM_RTX_CODE];
367 /* Generate the contents of the rtx_next array. This really doesn't belong
368 in gengtype at all, but it's needed for adjust_field_rtx_def. */
374 for (i = 0; i < NUM_RTX_CODE; i++)
379 if (strncmp (rtx_format[i], "iuu", 3) == 0)
381 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
384 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
385 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
390 /* Write out the contents of the rtx_next array. */
394 outf_p f = get_output_file_with_visibility (NULL);
397 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
398 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
399 for (i = 0; i < NUM_RTX_CODE; i++)
400 if (rtx_next[i] == -1)
401 oprintf (f, " 0,\n");
404 " offsetof (struct rtx_def, fld) + %d * sizeof (rtunion),\n",
409 /* Handle `special("rtx_def")'. This is a special case for field
410 `fld' of struct rtx_def, which is an array of unions whose values
411 are based in a complex way on the type of RTL. */
414 adjust_field_rtx_def (t, opt)
416 options_p opt ATTRIBUTE_UNUSED;
421 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
422 type_p bitmap_tp, basic_block_tp;
424 static const char * const rtx_name[NUM_RTX_CODE] = {
425 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
430 if (t->kind != TYPE_ARRAY)
432 error_at_line (&lexer_line,
433 "special `rtx_def' must be applied to an array");
437 nodot = xmalloc (sizeof (*nodot));
442 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
443 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
444 tree_tp = create_pointer (find_structure ("tree_node", 1));
445 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
446 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
447 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
448 scalar_tp = create_scalar_type ("rtunion scalar", 14);
451 pair_p note_flds = NULL;
454 for (c = 0; c < 3; c++)
456 pair_p old_note_flds = note_flds;
458 note_flds = xmalloc (sizeof (*note_flds));
459 note_flds->line.file = __FILE__;
460 note_flds->line.line = __LINE__;
461 note_flds->name = "rttree";
462 note_flds->type = tree_tp;
463 note_flds->opt = xmalloc (sizeof (*note_flds->opt));
464 note_flds->opt->next = nodot;
465 note_flds->opt->name = "tag";
466 note_flds->next = old_note_flds;
469 note_flds->type = rtx_tp;
470 note_flds->name = "rtx";
471 note_flds->opt->info = "NOTE_INSN_EXPECTED_VALUE";
472 note_flds->next->opt->info = "NOTE_INSN_BLOCK_BEG";
473 note_flds->next->next->opt->info = "NOTE_INSN_BLOCK_END";
475 new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL);
478 note_union_tp = find_structure ("rtx_def_note_subunion", 1);
480 for (i = 0; i < NUM_RTX_CODE; i++)
482 pair_p old_flds = flds;
483 pair_p subfields = NULL;
484 size_t aindex, nmindex;
488 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
490 pair_p old_subf = subfields;
494 switch (rtx_format[i][aindex])
505 if (i == MEM && aindex == 1)
506 t = mem_attrs_tp, subname = "rtmem";
507 else if (i == JUMP_INSN && aindex == 9)
508 t = rtx_tp, subname = "rtx";
509 else if (i == CODE_LABEL && aindex == 4)
510 t = scalar_tp, subname = "rtint";
511 else if (i == CODE_LABEL && aindex == 5)
512 t = rtx_tp, subname = "rtx";
513 else if (i == LABEL_REF
514 && (aindex == 1 || aindex == 2))
515 t = rtx_tp, subname = "rtx";
516 else if (i == NOTE && aindex == 4)
517 t = note_union_tp, subname = "";
518 else if (i == NOTE && aindex >= 7)
519 t = scalar_tp, subname = "rtint";
520 else if (i == ADDR_DIFF_VEC && aindex == 4)
521 t = scalar_tp, subname = "rtint";
522 else if (i == VALUE && aindex == 0)
523 t = scalar_tp, subname = "rtint";
524 else if (i == REG && aindex == 1)
525 t = scalar_tp, subname = "rtint";
526 else if (i == SCRATCH && aindex == 0)
527 t = scalar_tp, subname = "rtint";
528 else if (i == BARRIER && aindex >= 3)
529 t = scalar_tp, subname = "rtint";
532 error_at_line (&lexer_line,
533 "rtx type `%s' has `0' in position %lu, can't handle",
534 rtx_name[i], (unsigned long) aindex);
575 error_at_line (&lexer_line,
576 "rtx type `%s' has `%c' in position %lu, can't handle",
577 rtx_name[i], rtx_format[i][aindex],
578 (unsigned long)aindex);
584 subfields = xmalloc (sizeof (*subfields));
585 subfields->next = old_subf;
587 subfields->name = xasprintf ("[%lu].%s", (unsigned long)aindex,
589 subfields->line.file = __FILE__;
590 subfields->line.line = __LINE__;
591 if (t == note_union_tp)
593 subfields->opt = xmalloc (sizeof (*subfields->opt));
594 subfields->opt->next = nodot;
595 subfields->opt->name = "desc";
596 subfields->opt->info = "NOTE_LINE_NUMBER (&%0)";
598 else if (t == basic_block_tp)
600 /* We don't presently GC basic block structures... */
601 subfields->opt = xmalloc (sizeof (*subfields->opt));
602 subfields->opt->next = nodot;
603 subfields->opt->name = "skip";
604 subfields->opt->info = NULL;
607 subfields->opt = nodot;
610 flds = xmalloc (sizeof (*flds));
611 flds->next = old_flds;
613 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
614 new_structure (sname, 0, &lexer_line, subfields, NULL);
615 flds->type = find_structure (sname, 0);
616 flds->line.file = __FILE__;
617 flds->line.line = __LINE__;
618 flds->opt = xmalloc (sizeof (*flds->opt));
619 flds->opt->next = nodot;
620 flds->opt->name = "tag";
621 ftag = xstrdup (rtx_name[i]);
622 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
623 ftag[nmindex] = TOUPPER (ftag[nmindex]);
624 flds->opt->info = ftag;
627 new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
628 return find_structure ("rtx_def_subunion", 1);
631 /* Handle `special("tree_exp")'. This is a special case for
632 field `operands' of struct tree_exp, which although it claims to contain
633 pointers to trees, actually sometimes contains pointers to RTL too.
634 Passed T, the old type of the field, and OPT its options. Returns
635 a new type for the field. */
638 adjust_field_tree_exp (t, opt)
640 options_p opt ATTRIBUTE_UNUSED;
645 static const struct {
650 { "SAVE_EXPR", 2, 1 },
651 { "GOTO_SUBROUTINE_EXPR", 0, 2 },
652 { "RTL_EXPR", 0, 2 },
653 { "WITH_CLEANUP_EXPR", 2, 1 },
654 { "METHOD_CALL_EXPR", 3, 1 }
657 if (t->kind != TYPE_ARRAY)
659 error_at_line (&lexer_line,
660 "special `tree_exp' must be applied to an array");
664 nodot = xmalloc (sizeof (*nodot));
669 flds = xmalloc (sizeof (*flds));
673 flds->line.file = __FILE__;
674 flds->line.line = __LINE__;
675 flds->opt = xmalloc (sizeof (*flds->opt));
676 flds->opt->next = nodot;
677 flds->opt->name = "length";
678 flds->opt->info = "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
680 options_p oldopt = flds->opt;
681 flds->opt = xmalloc (sizeof (*flds->opt));
682 flds->opt->next = oldopt;
683 flds->opt->name = "default";
684 flds->opt->info = "";
687 for (i = 0; i < ARRAY_SIZE (data); i++)
689 pair_p old_flds = flds;
690 pair_p subfields = NULL;
695 r_index < data[i].first_rtl + data[i].num_rtl;
698 pair_p old_subf = subfields;
699 subfields = xmalloc (sizeof (*subfields));
700 subfields->next = old_subf;
701 subfields->name = xasprintf ("[%d]", r_index);
702 if (r_index < data[i].first_rtl)
703 subfields->type = t->u.a.p;
705 subfields->type = create_pointer (find_structure ("rtx_def", 0));
706 subfields->line.file = __FILE__;
707 subfields->line.line = __LINE__;
708 subfields->opt = nodot;
711 flds = xmalloc (sizeof (*flds));
712 flds->next = old_flds;
714 sname = xasprintf ("tree_exp_%s", data[i].name);
715 new_structure (sname, 0, &lexer_line, subfields, NULL);
716 flds->type = find_structure (sname, 0);
717 flds->line.file = __FILE__;
718 flds->line.line = __LINE__;
719 flds->opt = xmalloc (sizeof (*flds->opt));
720 flds->opt->next = nodot;
721 flds->opt->name = "tag";
722 flds->opt->info = data[i].name;
725 new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
726 return find_structure ("tree_exp_subunion", 1);
729 /* Perform any special processing on a type T, about to become the type
730 of a field. Return the appropriate type for the field.
732 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
733 - Similarly for arrays of pointer-to-char;
734 - Converts structures for which a parameter is provided to
736 - Handles "special" options.
740 adjust_field_type (t, opt)
745 const int pointer_p = t->kind == TYPE_POINTER;
746 type_p params[NUM_PARAM];
750 for (i = 0; i < NUM_PARAM; i++)
753 for (; opt; opt = opt->next)
754 if (strcmp (opt->name, "length") == 0)
756 else if (strcmp (opt->name, "param_is") == 0
757 || (strncmp (opt->name, "param", 5) == 0
758 && ISDIGIT (opt->name[5])
759 && strcmp (opt->name + 6, "_is") == 0))
761 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
763 if (! UNION_OR_STRUCT_P (t)
764 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
766 error_at_line (&lexer_line,
767 "option `%s' may only be applied to structures or structure pointers",
773 if (params[num] != NULL)
774 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
775 if (! ISDIGIT (opt->name[5]))
776 params[num] = create_pointer ((type_p) opt->info);
778 params[num] = (type_p) opt->info;
780 else if (strcmp (opt->name, "special") == 0)
782 const char *special_name = (const char *)opt->info;
783 if (strcmp (special_name, "tree_exp") == 0)
784 t = adjust_field_tree_exp (t, opt);
785 else if (strcmp (special_name, "rtx_def") == 0)
786 t = adjust_field_rtx_def (t, opt);
788 error_at_line (&lexer_line, "unknown special `%s'", special_name);
797 realt = find_param_structure (t, params);
798 t = pointer_p ? create_pointer (realt) : realt;
803 && t->u.p->kind == TYPE_SCALAR
804 && (strcmp (t->u.p->u.sc, "char") == 0
805 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
807 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
808 && t->u.a.p->u.p->kind == TYPE_SCALAR
809 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
810 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
811 return create_array (&string_type, t->u.a.len);
816 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
817 and information about the correspondance between token types and fields
818 in TYPEINFO. POS is used for error messages. */
821 note_yacc_type (o, fields, typeinfo, pos)
830 for (p = typeinfo; p; p = p->next)
837 if (p->type == (type_p) 1)
842 for (pp = typeinfo; pp; pp = pp->next)
843 if (pp->type != (type_p) 1
844 && strcmp (pp->opt->info, p->opt->info) == 0)
853 for (m = fields; m; m = m->next)
854 if (strcmp (m->name, p->name) == 0)
858 error_at_line (&p->line,
859 "couldn't match fieldname `%s'", p->name);
870 || p->type == (type_p) 1)
876 new_structure ("yy_union", 1, pos, typeinfo, o);
877 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
880 static void process_gc_options PARAMS ((options_p, enum gc_used_enum,
881 int *, int *, int *));
882 static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum, type_p *));
883 static void set_gc_used PARAMS ((pair_p));
885 /* Handle OPT for set_gc_used_type. */
888 process_gc_options (opt, level, maybe_undef, pass_param, length)
890 enum gc_used_enum level;
896 for (o = opt; o; o = o->next)
897 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
898 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
899 else if (strcmp (o->name, "maybe_undef") == 0)
901 else if (strcmp (o->name, "use_params") == 0)
903 else if (strcmp (o->name, "length") == 0)
907 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
910 set_gc_used_type (t, level, param)
912 enum gc_used_enum level;
913 type_p param[NUM_PARAM];
915 if (t->gc_used >= level)
928 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy);
930 for (f = t->u.s.fields; f; f = f->next)
935 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
938 if (length && f->type->kind == TYPE_POINTER)
939 set_gc_used_type (f->type->u.p, GC_USED, NULL);
940 else if (maybe_undef && f->type->kind == TYPE_POINTER)
941 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
942 else if (pass_param && f->type->kind == TYPE_POINTER && param)
943 set_gc_used_type (find_param_structure (f->type->u.p, param),
944 GC_POINTED_TO, NULL);
946 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
952 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
956 set_gc_used_type (t->u.a.p, GC_USED, param);
959 case TYPE_LANG_STRUCT:
960 for (t = t->u.s.lang_struct; t; t = t->next)
961 set_gc_used_type (t, level, param);
964 case TYPE_PARAM_STRUCT:
967 for (i = 0; i < NUM_PARAM; i++)
968 if (t->u.param_struct.param[i] != 0)
969 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
971 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
972 level = GC_POINTED_TO;
975 t->u.param_struct.stru->gc_used = GC_UNUSED;
976 set_gc_used_type (t->u.param_struct.stru, level,
977 t->u.param_struct.param);
985 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
988 set_gc_used (variables)
992 for (p = variables; p; p = p->next)
993 set_gc_used_type (p->type, GC_USED, NULL);
996 /* File mapping routines. For each input file, there is one output .c file
997 (but some output files have many input files), and there is one .h file
998 for the whole build. */
1000 /* The list of output files. */
1001 static outf_p output_files;
1003 /* The output header file that is included into pretty much every
1007 /* Number of files specified in gtfiles. */
1008 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1010 /* Number of files in the language files array. */
1011 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1013 /* Length of srcdir name. */
1014 static int srcdir_len = 0;
1016 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1017 outf_p base_files[NUM_BASE_FILES];
1019 static outf_p create_file PARAMS ((const char *, const char *));
1020 static const char * get_file_basename PARAMS ((const char *));
1022 /* Create and return an outf_p for a new file for NAME, to be called
1026 create_file (name, oname)
1030 static const char *const hdr[] = {
1031 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
1033 "This file is part of GCC.\n",
1035 "GCC is free software; you can redistribute it and/or modify it under\n",
1036 "the terms of the GNU General Public License as published by the Free\n",
1037 "Software Foundation; either version 2, or (at your option) any later\n",
1040 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1041 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1042 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1043 "for more details.\n",
1045 "You should have received a copy of the GNU General Public License\n",
1046 "along with GCC; see the file COPYING. If not, write to the Free\n",
1047 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
1048 "02111-1307, USA. */\n",
1050 "/* This file is machine generated. Do not edit. */\n"
1055 f = xcalloc (sizeof (*f), 1);
1056 f->next = output_files;
1060 oprintf (f, "/* Type information for %s.\n", name);
1061 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1062 oprintf (f, "%s", hdr[i]);
1066 /* Print, like fprintf, to O. */
1068 oprintf VPARAMS ((outf_p o, const char *format, ...))
1073 VA_OPEN (ap, format);
1074 VA_FIXEDARG (ap, outf_p, o);
1075 VA_FIXEDARG (ap, const char *, format);
1076 slength = xvasprintf (&s, format, ap);
1078 if (o->bufused + slength > o->buflength)
1080 size_t new_len = o->buflength;
1085 } while (o->bufused + slength >= new_len);
1086 o->buf = xrealloc (o->buf, new_len);
1087 o->buflength = new_len;
1089 memcpy (o->buf + o->bufused, s, slength);
1090 o->bufused += slength;
1095 /* Open the global header file and the language-specific header files. */
1102 header_file = create_file ("GCC", "gtype-desc.h");
1104 for (i = 0; i < NUM_BASE_FILES; i++)
1105 base_files[i] = create_file (lang_dir_names[i],
1106 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1108 /* gtype-desc.c is a little special, so we create it here. */
1110 /* The order of files here matters very much. */
1111 static const char *const ifiles [] = {
1112 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1113 "hashtab.h", "splay-tree.h", "bitmap.h", "tree.h", "rtl.h",
1114 "function.h", "insn-config.h", "expr.h", "hard-reg-set.h",
1115 "basic-block.h", "cselib.h", "insn-addr.h", "ssa.h", "optabs.h",
1116 "libfuncs.h", "debug.h", "ggc.h",
1119 const char *const *ifp;
1120 outf_p gtype_desc_c;
1122 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1123 for (ifp = ifiles; *ifp; ifp++)
1124 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1128 /* Determine the pathname to F relative to $(srcdir). */
1131 get_file_basename (f)
1134 const char *basename;
1137 basename = strrchr (f, '/');
1144 for (i = 1; i < NUM_BASE_FILES; i++)
1150 s1 = basename - strlen (lang_dir_names [i]) - 1;
1151 s2 = lang_dir_names [i];
1154 if (l1 >= l2 && !memcmp (s1, s2, l2))
1157 if ((basename - f - 1) != srcdir_len)
1158 abort (); /* Match is wrong - should be preceded by $srcdir. */
1166 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1167 INPUT_FILE is used by <lang>.
1169 This function should be written to assume that a file _is_ used
1170 if the situation is unclear. If it wrongly assumes a file _is_ used,
1171 a linker error will result. If it wrongly assumes a file _is not_ used,
1172 some GC roots may be missed, which is a much harder-to-debug problem. */
1175 get_base_file_bitmap (input_file)
1176 const char *input_file;
1178 const char *basename = get_file_basename (input_file);
1179 const char *slashpos = strchr (basename, '/');
1187 for (i = 1; i < NUM_BASE_FILES; i++)
1188 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1189 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1191 /* It's in a language directory, set that language. */
1196 abort (); /* Should have found the language. */
1199 /* If it's in any config-lang.in, then set for the languages
1204 for (j = 0; j < NUM_LANG_FILES; j++)
1206 if (!strcmp(input_file, lang_files[j]))
1208 for (k = 0; k < NUM_BASE_FILES; k++)
1210 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1216 /* Otherwise, set all languages. */
1218 bitmap = (1 << NUM_BASE_FILES) - 1;
1223 /* An output file, suitable for definitions, that can see declarations
1224 made in INPUT_FILE and is linked into every language that uses
1228 get_output_file_with_visibility (input_file)
1229 const char *input_file;
1233 const char *basename;
1234 const char *for_name;
1235 const char *output_name;
1237 /* This can happen when we need a file with visibility on a
1238 structure that we've never seen. We have to just hope that it's
1239 globally visible. */
1240 if (input_file == NULL)
1241 input_file = "system.h";
1243 /* Determine the output file name. */
1244 basename = get_file_basename (input_file);
1246 len = strlen (basename);
1247 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1248 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1249 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1253 output_name = s = xasprintf ("gt-%s", basename);
1254 for (; *s != '.'; s++)
1255 if (! ISALNUM (*s) && *s != '-')
1257 memcpy (s, ".h", sizeof (".h"));
1258 for_name = basename;
1260 else if (strcmp (basename, "c-common.h") == 0)
1261 output_name = "gt-c-common.h", for_name = "c-common.c";
1262 else if (strcmp (basename, "c-tree.h") == 0)
1263 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1268 for (i = 0; i < NUM_BASE_FILES; i++)
1269 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1270 && basename[strlen(lang_dir_names[i])] == '/')
1271 return base_files[i];
1273 output_name = "gtype-desc.c";
1277 /* Look through to see if we've ever seen this output filename before. */
1278 for (r = output_files; r; r = r->next)
1279 if (strcmp (r->name, output_name) == 0)
1282 /* If not, create it. */
1283 r = create_file (for_name, output_name);
1288 /* The name of an output file, suitable for definitions, that can see
1289 declarations made in INPUT_FILE and is linked into every language
1290 that uses INPUT_FILE. */
1293 get_output_file_name (input_file)
1294 const char *input_file;
1296 return get_output_file_with_visibility (input_file)->name;
1299 /* Copy the output to its final destination,
1300 but don't unnecessarily change modification times. */
1302 static void close_output_files PARAMS ((void));
1305 close_output_files ()
1309 for (of = output_files; of; of = of->next)
1313 newfile = fopen (of->name, "r");
1314 if (newfile != NULL )
1319 for (i = 0; i < of->bufused; i++)
1322 ch = fgetc (newfile);
1323 if (ch == EOF || ch != (unsigned char) of->buf[i])
1326 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1333 newfile = fopen (of->name, "w");
1334 if (newfile == NULL)
1336 perror ("opening output file");
1339 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1341 perror ("writing output file");
1344 if (fclose (newfile) != 0)
1346 perror ("closing output file");
1359 struct walk_type_data;
1361 /* For scalars and strings, given the item in 'val'.
1362 For structures, given a pointer to the item in 'val'.
1363 For misc. pointers, given the item in 'val'.
1365 typedef void (*process_field_fn)
1366 PARAMS ((type_p f, const struct walk_type_data *p));
1367 typedef void (*func_name_fn)
1368 PARAMS ((type_p s, const struct walk_type_data *p));
1370 /* Parameters for write_types. */
1372 struct write_types_data
1375 const char *param_prefix;
1376 const char *subfield_marker_routine;
1377 const char *marker_routine;
1378 const char *reorder_note_routine;
1379 const char *comment;
1382 static void output_escaped_param PARAMS ((struct walk_type_data *d,
1383 const char *, const char *));
1384 static void output_mangled_typename PARAMS ((outf_p, type_p));
1385 static void walk_type PARAMS ((type_p t, struct walk_type_data *d));
1386 static void write_func_for_structure
1387 PARAMS ((type_p orig_s, type_p s, type_p * param,
1388 const struct write_types_data *wtd));
1389 static void write_types_process_field
1390 PARAMS ((type_p f, const struct walk_type_data *d));
1391 static void write_types PARAMS ((type_p structures,
1392 type_p param_structs,
1393 const struct write_types_data *wtd));
1394 static void write_types_local_process_field
1395 PARAMS ((type_p f, const struct walk_type_data *d));
1396 static void write_local_func_for_structure
1397 PARAMS ((type_p orig_s, type_p s, type_p * param));
1398 static void write_local PARAMS ((type_p structures,
1399 type_p param_structs));
1400 static void write_enum_defn PARAMS ((type_p structures, type_p param_structs));
1401 static int contains_scalar_p PARAMS ((type_p t));
1402 static void put_mangled_filename PARAMS ((outf_p , const char *));
1403 static void finish_root_table PARAMS ((struct flist *flp, const char *pfx,
1404 const char *tname, const char *lastname,
1406 static void write_root PARAMS ((outf_p , pair_p, type_p, const char *, int,
1407 struct fileloc *, const char *));
1408 static void write_array PARAMS ((outf_p f, pair_p v,
1409 const struct write_types_data *wtd));
1410 static void write_roots PARAMS ((pair_p));
1412 /* Parameters for walk_type. */
1414 struct walk_type_data
1416 process_field_fn process_field;
1421 const char *prev_val[4];
1424 struct fileloc *line;
1429 const char *reorder_fn;
1432 /* Print a mangled name representing T to OF. */
1435 output_mangled_typename (of, t)
1441 else switch (t->kind)
1445 output_mangled_typename (of, t->u.p);
1455 case TYPE_LANG_STRUCT:
1456 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1458 case TYPE_PARAM_STRUCT:
1461 for (i = 0; i < NUM_PARAM; i++)
1462 if (t->u.param_struct.param[i] != NULL)
1463 output_mangled_typename (of, t->u.param_struct.param[i]);
1464 output_mangled_typename (of, t->u.param_struct.stru);
1472 /* Print PARAM to D->OF processing escapes. D->VAL references the
1473 current object, D->PREV_VAL the object containing the current
1474 object, ONAME is the name of the option and D->LINE is used to
1475 print error messages. */
1478 output_escaped_param (d, param, oname)
1479 struct walk_type_data *d;
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. D->PREV_VAL lists the objects containing the current object,
1518 D->OPT is a list of options to apply, D->INDENT is the current
1519 indentation level, D->LINE is used to print error messages,
1520 D->BITMAP indicates which languages to print the structure for, and
1521 D->PARAM is the current parameter (from an enclosing param_is
1527 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;
1534 int needs_cast_p = 0;
1537 for (oo = d->opt; oo; oo = oo->next)
1538 if (strcmp (oo->name, "length") == 0)
1539 length = (const char *)oo->info;
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)
1548 desc = (const char *)oo->info;
1549 else if (strcmp (oo->name, "dot") == 0)
1551 else if (strcmp (oo->name, "tag") == 0)
1553 else if (strcmp (oo->name, "special") == 0)
1555 else if (strcmp (oo->name, "skip") == 0)
1557 else if (strcmp (oo->name, "default") == 0)
1559 else if (strcmp (oo->name, "descbits") == 0)
1561 else if (strcmp (oo->name, "param_is") == 0)
1563 else if (strcmp (oo->name, "chain_next") == 0)
1565 else if (strcmp (oo->name, "chain_prev") == 0)
1567 else if (strcmp (oo->name, "reorder") == 0)
1570 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1577 int pointer_p = t->kind == TYPE_POINTER;
1581 if (! UNION_OR_STRUCT_P (t))
1582 error_at_line (d->line, "`use_params' option on unimplemented type");
1584 t = find_param_structure (t, d->param);
1586 t = create_pointer (t);
1589 if (use_param_num != -1)
1591 if (d->param != NULL && d->param[use_param_num] != NULL)
1593 type_p nt = d->param[use_param_num];
1595 if (t->kind == TYPE_ARRAY)
1596 nt = create_array (nt, t->u.a.len);
1597 else if (length != NULL && t->kind == TYPE_POINTER)
1598 nt = create_pointer (nt);
1599 needs_cast_p = (t->kind != TYPE_POINTER
1600 && nt->kind == TYPE_POINTER);
1604 error_at_line (d->line, "no parameter defined for `%s'",
1609 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1611 error_at_line (d->line,
1612 "field `%s' has invalid option `maybe_undef_p'\n",
1621 d->process_field (t, d);
1627 && t->u.p->u.s.line.file == NULL)
1629 oprintf (d->of, "%*sif (%s) abort();\n", d->indent, "", d->val);
1635 if (! UNION_OR_STRUCT_P (t->u.p)
1636 && t->u.p->kind != TYPE_PARAM_STRUCT)
1638 error_at_line (d->line,
1639 "field `%s' is pointer to unimplemented type",
1644 d->process_field (t->u.p, d);
1648 int loopcounter = d->counter++;
1649 const char *oldval = d->val;
1650 const char *oldprevval3 = d->prev_val[3];
1653 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1655 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1656 d->process_field(t, d);
1657 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1658 loopcounter, loopcounter);
1659 output_escaped_param (d, length, "length");
1660 oprintf (d->of, "); i%d++) {\n", loopcounter);
1662 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1664 d->prev_val[3] = oldval;
1665 walk_type (t->u.p, d);
1668 d->prev_val[3] = oldprevval3;
1671 oprintf (d->of, "%*s}\n", d->indent, "");
1673 oprintf (d->of, "%*s}\n", d->indent, "");
1680 int loopcounter = d->counter++;
1681 const char *oldval = d->val;
1684 /* If it's an array of scalars, we optimise by not generating
1686 if (t->u.a.p->kind == TYPE_SCALAR)
1689 oprintf (d->of, "%*s{\n", d->indent, "");
1691 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1692 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1693 loopcounter, loopcounter);
1695 output_escaped_param (d, length, "length");
1697 oprintf (d->of, "%s", t->u.a.len);
1698 oprintf (d->of, "); i%d++) {\n", loopcounter);
1700 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1702 walk_type (t->u.a.p, d);
1707 oprintf (d->of, "%*s}\n", d->indent, "");
1709 oprintf (d->of, "%*s}\n", d->indent, "");
1717 const char *oldval = d->val;
1718 const char *oldprevval1 = d->prev_val[1];
1719 const char *oldprevval2 = d->prev_val[2];
1720 const int union_p = t->kind == TYPE_UNION;
1721 int seen_default_p = 0;
1724 if (! t->u.s.line.file)
1725 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1727 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1729 error_at_line (d->line,
1730 "structure `%s' defined for mismatching languages",
1732 error_at_line (&t->u.s.line, "one structure defined here");
1735 /* Some things may also be defined in the structure's options. */
1736 for (o = t->u.s.opt; o; o = o->next)
1737 if (! desc && strcmp (o->name, "desc") == 0)
1738 desc = (const char *)o->info;
1740 d->prev_val[2] = oldval;
1741 d->prev_val[1] = oldprevval2;
1746 error_at_line (d->line, "missing `desc' option for union `%s'",
1750 oprintf (d->of, "%*sswitch (", d->indent, "");
1751 output_escaped_param (d, desc, "desc");
1752 oprintf (d->of, ")\n");
1754 oprintf (d->of, "%*s{\n", d->indent, "");
1756 for (f = t->u.s.fields; f; f = f->next)
1759 const char *dot = ".";
1760 const char *tagid = NULL;
1763 int use_param_p = 0;
1766 d->reorder_fn = NULL;
1767 for (oo = f->opt; oo; oo = oo->next)
1768 if (strcmp (oo->name, "dot") == 0)
1769 dot = (const char *)oo->info;
1770 else if (strcmp (oo->name, "tag") == 0)
1771 tagid = (const char *)oo->info;
1772 else if (strcmp (oo->name, "skip") == 0)
1774 else if (strcmp (oo->name, "default") == 0)
1776 else if (strcmp (oo->name, "reorder") == 0)
1777 d->reorder_fn = (const char *)oo->info;
1778 else if (strncmp (oo->name, "use_param", 9) == 0
1779 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1785 if (union_p && tagid)
1787 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1790 else if (union_p && default_p)
1792 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1796 else if (! union_p && (default_p || tagid))
1797 error_at_line (d->line,
1798 "can't use `%s' outside a union on field `%s'",
1799 default_p ? "default" : "tag", f->name);
1800 else if (union_p && ! (default_p || tagid)
1801 && f->type->kind == TYPE_SCALAR)
1804 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1805 d->line->file, d->line->line, f->name);
1808 else if (union_p && ! (default_p || tagid))
1809 error_at_line (d->line,
1810 "field `%s' is missing `tag' or `default' option",
1814 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1817 if (union_p && use_param_p && d->param == NULL)
1818 oprintf (d->of, "%*sabort();\n", d->indent, "");
1820 walk_type (f->type, d);
1826 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1830 d->reorder_fn = NULL;
1833 d->prev_val[1] = oldprevval1;
1834 d->prev_val[2] = oldprevval2;
1836 if (union_p && ! seen_default_p)
1838 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1839 oprintf (d->of, "%*s break;\n", d->indent, "");
1843 oprintf (d->of, "%*s}\n", d->indent, "");
1849 case TYPE_LANG_STRUCT:
1852 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1853 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1856 error_at_line (d->line, "structure `%s' differs between languages",
1863 case TYPE_PARAM_STRUCT:
1865 type_p *oldparam = d->param;
1867 d->param = t->u.param_struct.param;
1868 walk_type (t->u.param_struct.stru, d);
1869 d->param = oldparam;
1878 /* process_field routine for marking routines. */
1881 write_types_process_field (f, d)
1883 const struct walk_type_data *d;
1885 const struct write_types_data *wtd;
1886 wtd = (const struct write_types_data *) d->cookie;
1891 oprintf (d->of, "%*s%s (%s", d->indent, "",
1892 wtd->subfield_marker_routine, d->val);
1893 if (wtd->param_prefix)
1895 oprintf (d->of, ", %s", d->prev_val[3]);
1898 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1899 output_mangled_typename (d->of, d->orig_s);
1902 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1904 oprintf (d->of, ");\n");
1905 if (d->reorder_fn && wtd->reorder_note_routine)
1906 oprintf (d->of, "%*s%s (%s, %s, %s);\n", d->indent, "",
1907 wtd->reorder_note_routine, d->val,
1908 d->prev_val[3], d->reorder_fn);
1912 if (wtd->param_prefix == NULL)
1917 case TYPE_LANG_STRUCT:
1918 case TYPE_PARAM_STRUCT:
1919 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1920 output_mangled_typename (d->of, f);
1921 oprintf (d->of, " (%s);\n", d->val);
1922 if (d->reorder_fn && wtd->reorder_note_routine)
1923 oprintf (d->of, "%*s%s (%s, %s, %s);\n", d->indent, "",
1924 wtd->reorder_note_routine, d->val, d->val,
1936 /* For S, a structure that's part of ORIG_S, and using parameters
1937 PARAM, write out a routine that:
1938 - Takes a parameter, a void * but actually of type *S
1939 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1940 field of S or its substructures and (in some cases) things
1941 that are pointed to by S.
1945 write_func_for_structure (orig_s, s, param, wtd)
1949 const struct write_types_data *wtd;
1951 const char *fn = s->u.s.line.file;
1953 const char *chain_next = NULL;
1954 const char *chain_prev = NULL;
1956 struct walk_type_data d;
1958 /* This is a hack, and not the good kind either. */
1959 for (i = NUM_PARAM - 1; i >= 0; i--)
1960 if (param && param[i] && param[i]->kind == TYPE_POINTER
1961 && UNION_OR_STRUCT_P (param[i]->u.p))
1962 fn = param[i]->u.p->u.s.line.file;
1964 memset (&d, 0, sizeof (d));
1965 d.of = get_output_file_with_visibility (fn);
1967 for (opt = s->u.s.opt; opt; opt = opt->next)
1968 if (strcmp (opt->name, "chain_next") == 0)
1969 chain_next = (const char *) opt->info;
1970 else if (strcmp (opt->name, "chain_prev") == 0)
1971 chain_prev = (const char *) opt->info;
1973 if (chain_prev != NULL && chain_next == NULL)
1974 error_at_line (&s->u.s.line, "chain_prev without chain_next");
1976 d.process_field = write_types_process_field;
1980 d.line = &s->u.s.line;
1981 d.bitmap = s->u.s.bitmap;
1983 d.prev_val[0] = "*x";
1984 d.prev_val[1] = "not valid postage"; /* guarantee an error */
1985 d.prev_val[3] = "x";
1988 oprintf (d.of, "\n");
1989 oprintf (d.of, "void\n");
1991 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
1994 oprintf (d.of, "gt_%s_", wtd->prefix);
1995 output_mangled_typename (d.of, orig_s);
1997 oprintf (d.of, " (x_p)\n");
1998 oprintf (d.of, " void *x_p;\n");
1999 oprintf (d.of, "{\n");
2000 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2001 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2002 chain_next == NULL ? "const " : "",
2003 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2004 if (chain_next != NULL)
2005 oprintf (d.of, " %s %s * xlimit = x;\n",
2006 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2007 if (chain_next == NULL)
2009 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2010 if (wtd->param_prefix)
2012 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2013 output_mangled_typename (d.of, orig_s);
2015 oprintf (d.of, "))\n");
2019 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2020 if (wtd->param_prefix)
2022 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2023 output_mangled_typename (d.of, orig_s);
2025 oprintf (d.of, "))\n");
2026 oprintf (d.of, " xlimit = (");
2027 d.prev_val[2] = "*xlimit";
2028 output_escaped_param (&d, chain_next, "chain_next");
2029 oprintf (d.of, ");\n");
2030 if (chain_prev != NULL)
2032 oprintf (d.of, " if (x != xlimit)\n");
2033 oprintf (d.of, " for (;;)\n");
2034 oprintf (d.of, " {\n");
2035 oprintf (d.of, " %s %s * const xprev = (",
2036 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2038 d.prev_val[2] = "*x";
2039 output_escaped_param (&d, chain_prev, "chain_prev");
2040 oprintf (d.of, ");\n");
2041 oprintf (d.of, " if (xprev == NULL) break;\n");
2042 oprintf (d.of, " x = xprev;\n");
2043 oprintf (d.of, " (void) %s (xprev",
2044 wtd->marker_routine);
2045 if (wtd->param_prefix)
2047 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2048 output_mangled_typename (d.of, orig_s);
2050 oprintf (d.of, ");\n");
2051 oprintf (d.of, " }\n");
2053 oprintf (d.of, " while (x != xlimit)\n");
2055 oprintf (d.of, " {\n");
2057 d.prev_val[2] = "*x";
2061 if (chain_next != NULL)
2063 oprintf (d.of, " x = (");
2064 output_escaped_param (&d, chain_next, "chain_next");
2065 oprintf (d.of, ");\n");
2068 oprintf (d.of, " }\n");
2069 oprintf (d.of, "}\n");
2072 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2075 write_types (structures, param_structs, wtd)
2077 type_p param_structs;
2078 const struct write_types_data *wtd;
2082 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2083 for (s = structures; s; s = s->next)
2084 if (s->gc_used == GC_POINTED_TO
2085 || s->gc_used == GC_MAYBE_POINTED_TO)
2089 if (s->gc_used == GC_MAYBE_POINTED_TO
2090 && s->u.s.line.file == NULL)
2093 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2094 output_mangled_typename (header_file, s);
2095 oprintf (header_file, "(X) do { \\\n");
2096 oprintf (header_file,
2097 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2099 oprintf (header_file,
2102 for (opt = s->u.s.opt; opt; opt = opt->next)
2103 if (strcmp (opt->name, "ptr_alias") == 0)
2105 type_p t = (type_p) opt->info;
2106 if (t->kind == TYPE_STRUCT
2107 || t->kind == TYPE_UNION
2108 || t->kind == TYPE_LANG_STRUCT)
2109 oprintf (header_file,
2110 "#define gt_%sx_%s gt_%sx_%s\n",
2111 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2113 error_at_line (&s->u.s.line,
2114 "structure alias is not a structure");
2120 /* Declare the marker procedure only once. */
2121 oprintf (header_file,
2122 "extern void gt_%sx_%s PARAMS ((void *));\n",
2123 wtd->prefix, s->u.s.tag);
2125 if (s->u.s.line.file == NULL)
2127 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2132 if (s->kind == TYPE_LANG_STRUCT)
2135 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2136 write_func_for_structure (s, ss, NULL, wtd);
2139 write_func_for_structure (s, s, NULL, wtd);
2142 for (s = param_structs; s; s = s->next)
2143 if (s->gc_used == GC_POINTED_TO)
2145 type_p * param = s->u.param_struct.param;
2146 type_p stru = s->u.param_struct.stru;
2148 /* Declare the marker procedure. */
2149 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2150 output_mangled_typename (header_file, s);
2151 oprintf (header_file, " PARAMS ((void *));\n");
2153 if (stru->u.s.line.file == NULL)
2155 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2160 if (stru->kind == TYPE_LANG_STRUCT)
2163 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2164 write_func_for_structure (s, ss, param, wtd);
2167 write_func_for_structure (s, stru, param, wtd);
2171 static const struct write_types_data ggc_wtd =
2173 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2174 "GC marker procedures. "
2177 static const struct write_types_data pch_wtd =
2179 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2180 "gt_pch_note_reorder",
2181 "PCH type-walking procedures. "
2184 /* Write out the local pointer-walking routines. */
2186 /* process_field routine for local pointer-walking. */
2189 write_types_local_process_field (f, d)
2191 const struct walk_type_data *d;
2198 case TYPE_LANG_STRUCT:
2199 case TYPE_PARAM_STRUCT:
2201 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2203 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2214 /* For S, a structure that's part of ORIG_S, and using parameters
2215 PARAM, write out a routine that:
2216 - Is of type gt_note_pointers
2217 - If calls PROCESS_FIELD on each field of S or its substructures.
2221 write_local_func_for_structure (orig_s, s, param)
2226 const char *fn = s->u.s.line.file;
2228 struct walk_type_data d;
2230 /* This is a hack, and not the good kind either. */
2231 for (i = NUM_PARAM - 1; i >= 0; i--)
2232 if (param && param[i] && param[i]->kind == TYPE_POINTER
2233 && UNION_OR_STRUCT_P (param[i]->u.p))
2234 fn = param[i]->u.p->u.s.line.file;
2236 memset (&d, 0, sizeof (d));
2237 d.of = get_output_file_with_visibility (fn);
2239 d.process_field = write_types_local_process_field;
2241 d.line = &s->u.s.line;
2242 d.bitmap = s->u.s.bitmap;
2244 d.prev_val[0] = d.prev_val[2] = "*x";
2245 d.prev_val[1] = "not valid postage"; /* guarantee an error */
2246 d.prev_val[3] = "x";
2249 oprintf (d.of, "\n");
2250 oprintf (d.of, "void\n");
2251 oprintf (d.of, "gt_pch_p_");
2252 output_mangled_typename (d.of, orig_s);
2253 oprintf (d.of, " (this_obj, x_p, op, cookie)\n");
2254 oprintf (d.of, " void *this_obj ATTRIBUTE_UNUSED;\n");
2255 oprintf (d.of, " void *x_p;\n");
2256 oprintf (d.of, " gt_pointer_operator op ATTRIBUTE_UNUSED;\n");
2257 oprintf (d.of, " void *cookie ATTRIBUTE_UNUSED;\n");
2258 oprintf (d.of, "{\n");
2259 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2260 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2261 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2264 oprintf (d.of, "}\n");
2267 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2270 write_local (structures, param_structs)
2272 type_p param_structs;
2276 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2277 for (s = structures; s; s = s->next)
2278 if (s->gc_used == GC_POINTED_TO
2279 || s->gc_used == GC_MAYBE_POINTED_TO)
2283 if (s->u.s.line.file == NULL)
2286 for (opt = s->u.s.opt; opt; opt = opt->next)
2287 if (strcmp (opt->name, "ptr_alias") == 0)
2289 type_p t = (type_p) opt->info;
2290 if (t->kind == TYPE_STRUCT
2291 || t->kind == TYPE_UNION
2292 || t->kind == TYPE_LANG_STRUCT)
2294 oprintf (header_file, "#define gt_pch_p_");
2295 output_mangled_typename (header_file, s);
2296 oprintf (header_file, " gt_pch_p_");
2297 output_mangled_typename (header_file, t);
2298 oprintf (header_file, "\n");
2301 error_at_line (&s->u.s.line,
2302 "structure alias is not a structure");
2308 /* Declare the marker procedure only once. */
2309 oprintf (header_file, "extern void gt_pch_p_");
2310 output_mangled_typename (header_file, s);
2311 oprintf (header_file,
2312 "\n PARAMS ((void *, void *, gt_pointer_operator, void *));\n");
2314 if (s->kind == TYPE_LANG_STRUCT)
2317 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2318 write_local_func_for_structure (s, ss, NULL);
2321 write_local_func_for_structure (s, s, NULL);
2324 for (s = param_structs; s; s = s->next)
2325 if (s->gc_used == GC_POINTED_TO)
2327 type_p * param = s->u.param_struct.param;
2328 type_p stru = s->u.param_struct.stru;
2330 /* Declare the marker procedure. */
2331 oprintf (header_file, "extern void gt_pch_p_");
2332 output_mangled_typename (header_file, s);
2333 oprintf (header_file,
2334 "\n PARAMS ((void *, void *, gt_pointer_operator, void *));\n");
2336 if (stru->u.s.line.file == NULL)
2338 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2343 if (stru->kind == TYPE_LANG_STRUCT)
2346 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2347 write_local_func_for_structure (s, ss, param);
2350 write_local_func_for_structure (s, stru, param);
2354 /* Write out the 'enum' definition for gt_types_enum. */
2357 write_enum_defn (structures, param_structs)
2359 type_p param_structs;
2363 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2364 oprintf (header_file, "enum gt_types_enum {\n");
2365 for (s = structures; s; s = s->next)
2366 if (s->gc_used == GC_POINTED_TO
2367 || s->gc_used == GC_MAYBE_POINTED_TO)
2369 if (s->gc_used == GC_MAYBE_POINTED_TO
2370 && s->u.s.line.file == NULL)
2373 oprintf (header_file, " gt_ggc_e_");
2374 output_mangled_typename (header_file, s);
2375 oprintf (header_file, ", \n");
2377 for (s = param_structs; s; s = s->next)
2378 if (s->gc_used == GC_POINTED_TO)
2380 oprintf (header_file, " gt_e_");
2381 output_mangled_typename (header_file, s);
2382 oprintf (header_file, ", \n");
2384 oprintf (header_file, " gt_types_enum_last\n");
2385 oprintf (header_file, "};\n");
2388 /* Might T contain any non-pointer elements? */
2391 contains_scalar_p (t)
2400 return contains_scalar_p (t->u.a.p);
2402 /* Could also check for structures that have no non-pointer
2403 fields, but there aren't enough of those to worry about. */
2408 /* Mangle FN and print it to F. */
2411 put_mangled_filename (f, fn)
2415 const char *name = get_output_file_name (fn);
2416 for (; *name != 0; name++)
2417 if (ISALNUM (*name))
2418 oprintf (f, "%c", *name);
2420 oprintf (f, "%c", '_');
2423 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2424 LASTNAME, and NAME are all strings to insert in various places in
2425 the resulting code. */
2428 finish_root_table (flp, pfx, lastname, tname, name)
2432 const char *lastname;
2437 for (fli2 = flp; fli2; fli2 = fli2->next)
2438 if (fli2->started_p)
2440 oprintf (fli2->f, " %s\n", lastname);
2441 oprintf (fli2->f, "};\n\n");
2444 for (fli2 = flp; fli2; fli2 = fli2->next)
2445 if (fli2->started_p)
2447 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2450 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2453 oprintf (base_files[fnum],
2454 "extern const struct %s gt_%s_",
2456 put_mangled_filename (base_files[fnum], fli2->name);
2457 oprintf (base_files[fnum], "[];\n");
2463 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2464 oprintf (base_files [fnum],
2465 "const struct %s * const %s[] = {\n",
2470 for (fli2 = flp; fli2; fli2 = fli2->next)
2471 if (fli2->started_p)
2473 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2476 fli2->started_p = 0;
2478 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2481 oprintf (base_files[fnum], " gt_%s_", pfx);
2482 put_mangled_filename (base_files[fnum], fli2->name);
2483 oprintf (base_files[fnum], ",\n");
2489 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2491 oprintf (base_files[fnum], " NULL\n");
2492 oprintf (base_files[fnum], "};\n");
2497 /* Write out to F the table entry and any marker routines needed to
2498 mark NAME as TYPE. The original variable is V, at LINE.
2499 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2500 is nonzero iff we are building the root table for hash table caches. */
2503 write_root (f, v, type, name, has_length, line, if_marked)
2509 struct fileloc *line;
2510 const char *if_marked;
2517 for (fld = type->u.s.fields; fld; fld = fld->next)
2520 const char *desc = NULL;
2523 for (o = fld->opt; o; o = o->next)
2524 if (strcmp (o->name, "skip") == 0)
2526 else if (strcmp (o->name, "desc") == 0)
2527 desc = (const char *)o->info;
2529 error_at_line (line,
2530 "field `%s' of global `%s' has unknown option `%s'",
2531 fld->name, name, o->name);
2535 else if (desc && fld->type->kind == TYPE_UNION)
2537 pair_p validf = NULL;
2540 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2542 const char *tag = NULL;
2545 for (oo = ufld->opt; oo; oo = oo->next)
2546 if (strcmp (oo->name, "tag") == 0)
2547 tag = (const char *)oo->info;
2548 if (tag == NULL || strcmp (tag, desc) != 0)
2551 error_at_line (line,
2552 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2553 name, fld->name, validf->name,
2554 name, fld->name, ufld->name,
2561 newname = xasprintf ("%s.%s.%s",
2562 name, fld->name, validf->name);
2563 write_root (f, v, validf->type, newname, 0, line,
2569 error_at_line (line,
2570 "global `%s.%s' has `desc' option but is not union",
2575 newname = xasprintf ("%s.%s", name, fld->name);
2576 write_root (f, v, fld->type, newname, 0, line, if_marked);
2586 newname = xasprintf ("%s[0]", name);
2587 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2596 oprintf (f, " {\n");
2597 oprintf (f, " &%s,\n", name);
2600 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2602 oprintf (f, " * (%s)", ap->u.a.len);
2603 else if (ap == v->type)
2604 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2606 oprintf (f, " sizeof (%s", v->name);
2607 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2609 oprintf (f, "),\n");
2613 if (! has_length && UNION_OR_STRUCT_P (tp))
2615 oprintf (f, " >_ggc_mx_%s,\n", tp->u.s.tag);
2616 oprintf (f, " >_pch_nx_%s", tp->u.s.tag);
2618 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2620 oprintf (f, " >_ggc_m_");
2621 output_mangled_typename (f, tp);
2622 oprintf (f, ",\n >_pch_n_");
2623 output_mangled_typename (f, tp);
2626 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2628 oprintf (f, " >_ggc_ma_%s,\n", name);
2629 oprintf (f, " >_pch_na_%s", name);
2633 error_at_line (line,
2634 "global `%s' is pointer to unimplemented type",
2638 oprintf (f, ",\n &%s", if_marked);
2639 oprintf (f, "\n },\n");
2645 oprintf (f, " {\n");
2646 oprintf (f, " &%s,\n", name);
2647 oprintf (f, " 1, \n");
2648 oprintf (f, " sizeof (%s),\n", v->name);
2649 oprintf (f, " >_ggc_m_S,\n");
2650 oprintf (f, " >_pch_n_S\n");
2651 oprintf (f, " },\n");
2659 error_at_line (line,
2660 "global `%s' is unimplemented type",
2665 /* This generates a routine to walk an array. */
2668 write_array (f, v, wtd)
2671 const struct write_types_data *wtd;
2673 struct walk_type_data d;
2676 memset (&d, 0, sizeof (d));
2682 d.bitmap = get_base_file_bitmap (v->line.file);
2685 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2687 if (wtd->param_prefix)
2689 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2691 " PARAMS ((void *, void *, gt_pointer_operator, void *));\n");
2692 oprintf (f, "static void gt_%sa_%s (this_obj, x_p, op, cookie)\n",
2693 wtd->param_prefix, v->name);
2694 oprintf (d.of, " void *this_obj ATTRIBUTE_UNUSED;\n");
2695 oprintf (d.of, " void *x_p ATTRIBUTE_UNUSED;\n");
2696 oprintf (d.of, " gt_pointer_operator op ATTRIBUTE_UNUSED;\n");
2697 oprintf (d.of, " void *cookie ATTRIBUTE_UNUSED;\n");
2698 oprintf (d.of, "{\n");
2699 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2700 d.process_field = write_types_local_process_field;
2701 walk_type (v->type, &d);
2702 oprintf (f, "}\n\n");
2706 oprintf (f, "static void gt_%sa_%s PARAMS ((void *));\n",
2707 wtd->prefix, v->name);
2708 oprintf (f, "static void\ngt_%sa_%s (x_p)\n",
2709 wtd->prefix, v->name);
2710 oprintf (f, " void *x_p ATTRIBUTE_UNUSED;\n");
2712 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2713 d.process_field = write_types_process_field;
2714 walk_type (v->type, &d);
2716 oprintf (f, "}\n\n");
2719 /* Output a table describing the locations and types of VARIABLES. */
2722 write_roots (variables)
2726 struct flist *flp = NULL;
2728 for (v = variables; v; v = v->next)
2730 outf_p f = get_output_file_with_visibility (v->line.file);
2732 const char *length = NULL;
2733 int deletable_p = 0;
2736 for (o = v->opt; o; o = o->next)
2737 if (strcmp (o->name, "length") == 0)
2738 length = (const char *)o->info;
2739 else if (strcmp (o->name, "deletable") == 0)
2741 else if (strcmp (o->name, "param_is") == 0)
2743 else if (strncmp (o->name, "param", 5) == 0
2744 && ISDIGIT (o->name[5])
2745 && strcmp (o->name + 6, "_is") == 0)
2747 else if (strcmp (o->name, "if_marked") == 0)
2750 error_at_line (&v->line,
2751 "global `%s' has unknown option `%s'",
2754 for (fli = flp; fli; fli = fli->next)
2759 fli = xmalloc (sizeof (*fli));
2763 fli->name = v->line.file;
2766 oprintf (f, "\n/* GC roots. */\n\n");
2771 && v->type->kind == TYPE_POINTER
2772 && (v->type->u.p->kind == TYPE_POINTER
2773 || v->type->u.p->kind == TYPE_STRUCT))
2775 write_array (f, v, &ggc_wtd);
2776 write_array (f, v, &pch_wtd);
2780 for (v = variables; v; v = v->next)
2782 outf_p f = get_output_file_with_visibility (v->line.file);
2788 for (o = v->opt; o; o = o->next)
2789 if (strcmp (o->name, "length") == 0)
2791 else if (strcmp (o->name, "deletable") == 0
2792 || strcmp (o->name, "if_marked") == 0)
2798 for (fli = flp; fli; fli = fli->next)
2801 if (! fli->started_p)
2805 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2806 put_mangled_filename (f, v->line.file);
2807 oprintf (f, "[] = {\n");
2810 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2813 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2816 for (v = variables; v; v = v->next)
2818 outf_p f = get_output_file_with_visibility (v->line.file);
2823 for (o = v->opt; o; o = o->next)
2824 if (strcmp (o->name, "deletable") == 0)
2826 else if (strcmp (o->name, "if_marked") == 0)
2832 for (fli = flp; fli; fli = fli->next)
2835 if (! fli->started_p)
2839 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2840 put_mangled_filename (f, v->line.file);
2841 oprintf (f, "[] = {\n");
2844 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2848 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2849 "gt_ggc_deletable_rtab");
2851 for (v = variables; v; v = v->next)
2853 outf_p f = get_output_file_with_visibility (v->line.file);
2855 const char *if_marked = NULL;
2859 for (o = v->opt; o; o = o->next)
2860 if (strcmp (o->name, "length") == 0)
2862 else if (strcmp (o->name, "if_marked") == 0)
2863 if_marked = (const char *) o->info;
2865 if (if_marked == NULL)
2868 if (v->type->kind != TYPE_POINTER
2869 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2870 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2872 error_at_line (&v->line, "if_marked option used but not hash table");
2876 for (fli = flp; fli; fli = fli->next)
2879 if (! fli->started_p)
2883 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2884 put_mangled_filename (f, v->line.file);
2885 oprintf (f, "[] = {\n");
2888 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2889 v->name, length_p, &v->line, if_marked);
2892 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2893 "gt_ggc_cache_rtab");
2895 for (v = variables; v; v = v->next)
2897 outf_p f = get_output_file_with_visibility (v->line.file);
2900 int if_marked_p = 0;
2903 for (o = v->opt; o; o = o->next)
2904 if (strcmp (o->name, "length") == 0)
2906 else if (strcmp (o->name, "if_marked") == 0)
2912 for (fli = flp; fli; fli = fli->next)
2915 if (! fli->started_p)
2919 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2920 put_mangled_filename (f, v->line.file);
2921 oprintf (f, "[] = {\n");
2924 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2927 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2928 "gt_pch_cache_rtab");
2930 for (v = variables; v; v = v->next)
2932 outf_p f = get_output_file_with_visibility (v->line.file);
2937 for (o = v->opt; o; o = o->next)
2938 if (strcmp (o->name, "deletable") == 0
2939 || strcmp (o->name, "if_marked") == 0)
2945 if (! contains_scalar_p (v->type))
2948 for (fli = flp; fli; fli = fli->next)
2951 if (! fli->started_p)
2955 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2956 put_mangled_filename (f, v->line.file);
2957 oprintf (f, "[] = {\n");
2960 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2964 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2965 "gt_pch_scalar_rtab");
2969 extern int main PARAMS ((int argc, char **argv));
2972 int argc ATTRIBUTE_UNUSED;
2973 char **argv ATTRIBUTE_UNUSED;
2976 static struct fileloc pos = { __FILE__, __LINE__ };
2981 srcdir_len = strlen (srcdir);
2983 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
2984 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
2985 do_scalar_typedef ("uint8", &pos);
2986 do_scalar_typedef ("jword", &pos);
2987 do_scalar_typedef ("JCF_u2", &pos);
2989 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
2992 do_typedef ("HARD_REG_SET", create_array (
2993 create_scalar_type ("unsigned long", strlen ("unsigned long")),
2996 for (i = 0; i < NUM_GT_FILES; i++)
2999 /* Omit if already seen. */
3000 for (j = 0; j < i; j++)
3002 if (!strcmp (all_files[i], all_files[j]))
3009 parse_file (all_files[i]);
3015 set_gc_used (variables);
3018 write_enum_defn (structures, param_structs);
3019 write_types (structures, param_structs, &ggc_wtd);
3020 write_types (structures, param_structs, &pch_wtd);
3021 write_local (structures, param_structs);
3022 write_roots (variables);
3024 close_output_files ();
3026 return (hit_error != 0);