1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003 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, reg_attrs_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 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
447 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
448 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
449 scalar_tp = create_scalar_type ("rtunion scalar", 14);
452 pair_p note_flds = NULL;
455 for (c = 0; c < 3; c++)
457 pair_p old_note_flds = note_flds;
459 note_flds = xmalloc (sizeof (*note_flds));
460 note_flds->line.file = __FILE__;
461 note_flds->line.line = __LINE__;
462 note_flds->name = "rttree";
463 note_flds->type = tree_tp;
464 note_flds->opt = xmalloc (sizeof (*note_flds->opt));
465 note_flds->opt->next = nodot;
466 note_flds->opt->name = "tag";
467 note_flds->next = old_note_flds;
470 note_flds->type = rtx_tp;
471 note_flds->name = "rtx";
472 note_flds->opt->info = "NOTE_INSN_EXPECTED_VALUE";
473 note_flds->next->opt->info = "NOTE_INSN_BLOCK_BEG";
474 note_flds->next->next->opt->info = "NOTE_INSN_BLOCK_END";
476 new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL);
479 note_union_tp = find_structure ("rtx_def_note_subunion", 1);
481 for (i = 0; i < NUM_RTX_CODE; i++)
483 pair_p old_flds = flds;
484 pair_p subfields = NULL;
485 size_t aindex, nmindex;
489 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
491 pair_p old_subf = subfields;
495 switch (rtx_format[i][aindex])
506 if (i == MEM && aindex == 1)
507 t = mem_attrs_tp, subname = "rtmem";
508 else if (i == JUMP_INSN && aindex == 9)
509 t = rtx_tp, subname = "rtx";
510 else if (i == CODE_LABEL && aindex == 4)
511 t = scalar_tp, subname = "rtint";
512 else if (i == CODE_LABEL && aindex == 5)
513 t = rtx_tp, subname = "rtx";
514 else if (i == LABEL_REF
515 && (aindex == 1 || aindex == 2))
516 t = rtx_tp, subname = "rtx";
517 else if (i == NOTE && aindex == 4)
518 t = note_union_tp, subname = "";
519 else if (i == NOTE && aindex >= 7)
520 t = scalar_tp, subname = "rtint";
521 else if (i == ADDR_DIFF_VEC && aindex == 4)
522 t = scalar_tp, subname = "rtint";
523 else if (i == VALUE && aindex == 0)
524 t = scalar_tp, subname = "rtint";
525 else if (i == REG && aindex == 1)
526 t = scalar_tp, subname = "rtint";
527 else if (i == REG && aindex == 2)
528 t = reg_attrs_tp, subname = "rtreg";
529 else if (i == SCRATCH && aindex == 0)
530 t = scalar_tp, subname = "rtint";
531 else if (i == BARRIER && aindex >= 3)
532 t = scalar_tp, subname = "rtint";
535 error_at_line (&lexer_line,
536 "rtx type `%s' has `0' in position %lu, can't handle",
537 rtx_name[i], (unsigned long) aindex);
578 error_at_line (&lexer_line,
579 "rtx type `%s' has `%c' in position %lu, can't handle",
580 rtx_name[i], rtx_format[i][aindex],
581 (unsigned long)aindex);
587 subfields = xmalloc (sizeof (*subfields));
588 subfields->next = old_subf;
590 subfields->name = xasprintf ("[%lu].%s", (unsigned long)aindex,
592 subfields->line.file = __FILE__;
593 subfields->line.line = __LINE__;
594 if (t == note_union_tp)
596 subfields->opt = xmalloc (sizeof (*subfields->opt));
597 subfields->opt->next = nodot;
598 subfields->opt->name = "desc";
599 subfields->opt->info = "NOTE_LINE_NUMBER (&%0)";
601 else if (t == basic_block_tp)
603 /* We don't presently GC basic block structures... */
604 subfields->opt = xmalloc (sizeof (*subfields->opt));
605 subfields->opt->next = nodot;
606 subfields->opt->name = "skip";
607 subfields->opt->info = NULL;
610 subfields->opt = nodot;
613 flds = xmalloc (sizeof (*flds));
614 flds->next = old_flds;
616 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
617 new_structure (sname, 0, &lexer_line, subfields, NULL);
618 flds->type = find_structure (sname, 0);
619 flds->line.file = __FILE__;
620 flds->line.line = __LINE__;
621 flds->opt = xmalloc (sizeof (*flds->opt));
622 flds->opt->next = nodot;
623 flds->opt->name = "tag";
624 ftag = xstrdup (rtx_name[i]);
625 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
626 ftag[nmindex] = TOUPPER (ftag[nmindex]);
627 flds->opt->info = ftag;
630 new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
631 return find_structure ("rtx_def_subunion", 1);
634 /* Handle `special("tree_exp")'. This is a special case for
635 field `operands' of struct tree_exp, which although it claims to contain
636 pointers to trees, actually sometimes contains pointers to RTL too.
637 Passed T, the old type of the field, and OPT its options. Returns
638 a new type for the field. */
641 adjust_field_tree_exp (t, opt)
643 options_p opt ATTRIBUTE_UNUSED;
648 static const struct {
653 { "SAVE_EXPR", 2, 1 },
654 { "GOTO_SUBROUTINE_EXPR", 0, 2 },
655 { "RTL_EXPR", 0, 2 },
656 { "WITH_CLEANUP_EXPR", 2, 1 },
657 { "METHOD_CALL_EXPR", 3, 1 }
660 if (t->kind != TYPE_ARRAY)
662 error_at_line (&lexer_line,
663 "special `tree_exp' must be applied to an array");
667 nodot = xmalloc (sizeof (*nodot));
672 flds = xmalloc (sizeof (*flds));
676 flds->line.file = __FILE__;
677 flds->line.line = __LINE__;
678 flds->opt = xmalloc (sizeof (*flds->opt));
679 flds->opt->next = nodot;
680 flds->opt->name = "length";
681 flds->opt->info = "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
683 options_p oldopt = flds->opt;
684 flds->opt = xmalloc (sizeof (*flds->opt));
685 flds->opt->next = oldopt;
686 flds->opt->name = "default";
687 flds->opt->info = "";
690 for (i = 0; i < ARRAY_SIZE (data); i++)
692 pair_p old_flds = flds;
693 pair_p subfields = NULL;
698 r_index < data[i].first_rtl + data[i].num_rtl;
701 pair_p old_subf = subfields;
702 subfields = xmalloc (sizeof (*subfields));
703 subfields->next = old_subf;
704 subfields->name = xasprintf ("[%d]", r_index);
705 if (r_index < data[i].first_rtl)
706 subfields->type = t->u.a.p;
708 subfields->type = create_pointer (find_structure ("rtx_def", 0));
709 subfields->line.file = __FILE__;
710 subfields->line.line = __LINE__;
711 subfields->opt = nodot;
714 flds = xmalloc (sizeof (*flds));
715 flds->next = old_flds;
717 sname = xasprintf ("tree_exp_%s", data[i].name);
718 new_structure (sname, 0, &lexer_line, subfields, NULL);
719 flds->type = find_structure (sname, 0);
720 flds->line.file = __FILE__;
721 flds->line.line = __LINE__;
722 flds->opt = xmalloc (sizeof (*flds->opt));
723 flds->opt->next = nodot;
724 flds->opt->name = "tag";
725 flds->opt->info = data[i].name;
728 new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
729 return find_structure ("tree_exp_subunion", 1);
732 /* Perform any special processing on a type T, about to become the type
733 of a field. Return the appropriate type for the field.
735 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
736 - Similarly for arrays of pointer-to-char;
737 - Converts structures for which a parameter is provided to
739 - Handles "special" options.
743 adjust_field_type (t, opt)
748 const int pointer_p = t->kind == TYPE_POINTER;
749 type_p params[NUM_PARAM];
753 for (i = 0; i < NUM_PARAM; i++)
756 for (; opt; opt = opt->next)
757 if (strcmp (opt->name, "length") == 0)
759 else if (strcmp (opt->name, "param_is") == 0
760 || (strncmp (opt->name, "param", 5) == 0
761 && ISDIGIT (opt->name[5])
762 && strcmp (opt->name + 6, "_is") == 0))
764 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
766 if (! UNION_OR_STRUCT_P (t)
767 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
769 error_at_line (&lexer_line,
770 "option `%s' may only be applied to structures or structure pointers",
776 if (params[num] != NULL)
777 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
778 if (! ISDIGIT (opt->name[5]))
779 params[num] = create_pointer ((type_p) opt->info);
781 params[num] = (type_p) opt->info;
783 else if (strcmp (opt->name, "special") == 0)
785 const char *special_name = (const char *)opt->info;
786 if (strcmp (special_name, "tree_exp") == 0)
787 t = adjust_field_tree_exp (t, opt);
788 else if (strcmp (special_name, "rtx_def") == 0)
789 t = adjust_field_rtx_def (t, opt);
791 error_at_line (&lexer_line, "unknown special `%s'", special_name);
800 realt = find_param_structure (t, params);
801 t = pointer_p ? create_pointer (realt) : realt;
806 && t->u.p->kind == TYPE_SCALAR
807 && (strcmp (t->u.p->u.sc, "char") == 0
808 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
810 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
811 && t->u.a.p->u.p->kind == TYPE_SCALAR
812 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
813 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
814 return create_array (&string_type, t->u.a.len);
819 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
820 and information about the correspondence between token types and fields
821 in TYPEINFO. POS is used for error messages. */
824 note_yacc_type (o, fields, typeinfo, pos)
833 for (p = typeinfo; p; p = p->next)
840 if (p->type == (type_p) 1)
845 for (pp = typeinfo; pp; pp = pp->next)
846 if (pp->type != (type_p) 1
847 && strcmp (pp->opt->info, p->opt->info) == 0)
856 for (m = fields; m; m = m->next)
857 if (strcmp (m->name, p->name) == 0)
861 error_at_line (&p->line,
862 "couldn't match fieldname `%s'", p->name);
873 || p->type == (type_p) 1)
879 new_structure ("yy_union", 1, pos, typeinfo, o);
880 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
883 static void process_gc_options PARAMS ((options_p, enum gc_used_enum,
884 int *, int *, int *));
885 static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum, type_p *));
886 static void set_gc_used PARAMS ((pair_p));
888 /* Handle OPT for set_gc_used_type. */
891 process_gc_options (opt, level, maybe_undef, pass_param, length)
893 enum gc_used_enum level;
899 for (o = opt; o; o = o->next)
900 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
901 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
902 else if (strcmp (o->name, "maybe_undef") == 0)
904 else if (strcmp (o->name, "use_params") == 0)
906 else if (strcmp (o->name, "length") == 0)
910 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
913 set_gc_used_type (t, level, param)
915 enum gc_used_enum level;
916 type_p param[NUM_PARAM];
918 if (t->gc_used >= level)
931 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy);
933 for (f = t->u.s.fields; f; f = f->next)
938 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
941 if (length && f->type->kind == TYPE_POINTER)
942 set_gc_used_type (f->type->u.p, GC_USED, NULL);
943 else if (maybe_undef && f->type->kind == TYPE_POINTER)
944 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
945 else if (pass_param && f->type->kind == TYPE_POINTER && param)
946 set_gc_used_type (find_param_structure (f->type->u.p, param),
947 GC_POINTED_TO, NULL);
949 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
955 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
959 set_gc_used_type (t->u.a.p, GC_USED, param);
962 case TYPE_LANG_STRUCT:
963 for (t = t->u.s.lang_struct; t; t = t->next)
964 set_gc_used_type (t, level, param);
967 case TYPE_PARAM_STRUCT:
970 for (i = 0; i < NUM_PARAM; i++)
971 if (t->u.param_struct.param[i] != 0)
972 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
974 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
975 level = GC_POINTED_TO;
978 t->u.param_struct.stru->gc_used = GC_UNUSED;
979 set_gc_used_type (t->u.param_struct.stru, level,
980 t->u.param_struct.param);
988 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
991 set_gc_used (variables)
995 for (p = variables; p; p = p->next)
996 set_gc_used_type (p->type, GC_USED, NULL);
999 /* File mapping routines. For each input file, there is one output .c file
1000 (but some output files have many input files), and there is one .h file
1001 for the whole build. */
1003 /* The list of output files. */
1004 static outf_p output_files;
1006 /* The output header file that is included into pretty much every
1010 /* Number of files specified in gtfiles. */
1011 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1013 /* Number of files in the language files array. */
1014 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1016 /* Length of srcdir name. */
1017 static int srcdir_len = 0;
1019 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1020 outf_p base_files[NUM_BASE_FILES];
1022 static outf_p create_file PARAMS ((const char *, const char *));
1023 static const char * get_file_basename PARAMS ((const char *));
1025 /* Create and return an outf_p for a new file for NAME, to be called
1029 create_file (name, oname)
1033 static const char *const hdr[] = {
1034 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
1036 "This file is part of GCC.\n",
1038 "GCC is free software; you can redistribute it and/or modify it under\n",
1039 "the terms of the GNU General Public License as published by the Free\n",
1040 "Software Foundation; either version 2, or (at your option) any later\n",
1043 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1044 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1045 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1046 "for more details.\n",
1048 "You should have received a copy of the GNU General Public License\n",
1049 "along with GCC; see the file COPYING. If not, write to the Free\n",
1050 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
1051 "02111-1307, USA. */\n",
1053 "/* This file is machine generated. Do not edit. */\n"
1058 f = xcalloc (sizeof (*f), 1);
1059 f->next = output_files;
1063 oprintf (f, "/* Type information for %s.\n", name);
1064 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1065 oprintf (f, "%s", hdr[i]);
1069 /* Print, like fprintf, to O. */
1071 oprintf VPARAMS ((outf_p o, const char *format, ...))
1076 VA_OPEN (ap, format);
1077 VA_FIXEDARG (ap, outf_p, o);
1078 VA_FIXEDARG (ap, const char *, format);
1079 slength = xvasprintf (&s, format, ap);
1081 if (o->bufused + slength > o->buflength)
1083 size_t new_len = o->buflength;
1088 } while (o->bufused + slength >= new_len);
1089 o->buf = xrealloc (o->buf, new_len);
1090 o->buflength = new_len;
1092 memcpy (o->buf + o->bufused, s, slength);
1093 o->bufused += slength;
1098 /* Open the global header file and the language-specific header files. */
1105 header_file = create_file ("GCC", "gtype-desc.h");
1107 for (i = 0; i < NUM_BASE_FILES; i++)
1108 base_files[i] = create_file (lang_dir_names[i],
1109 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1111 /* gtype-desc.c is a little special, so we create it here. */
1113 /* The order of files here matters very much. */
1114 static const char *const ifiles [] = {
1115 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1116 "hashtab.h", "splay-tree.h", "bitmap.h", "tree.h", "rtl.h",
1117 "function.h", "insn-config.h", "expr.h", "hard-reg-set.h",
1118 "basic-block.h", "cselib.h", "insn-addr.h", "ssa.h", "optabs.h",
1119 "libfuncs.h", "debug.h", "ggc.h",
1122 const char *const *ifp;
1123 outf_p gtype_desc_c;
1125 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1126 for (ifp = ifiles; *ifp; ifp++)
1127 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1131 /* Determine the pathname to F relative to $(srcdir). */
1134 get_file_basename (f)
1137 const char *basename;
1140 basename = strrchr (f, '/');
1147 for (i = 1; i < NUM_BASE_FILES; i++)
1153 s1 = basename - strlen (lang_dir_names [i]) - 1;
1154 s2 = lang_dir_names [i];
1157 if (l1 >= l2 && !memcmp (s1, s2, l2))
1160 if ((basename - f - 1) != srcdir_len)
1161 abort (); /* Match is wrong - should be preceded by $srcdir. */
1169 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1170 INPUT_FILE is used by <lang>.
1172 This function should be written to assume that a file _is_ used
1173 if the situation is unclear. If it wrongly assumes a file _is_ used,
1174 a linker error will result. If it wrongly assumes a file _is not_ used,
1175 some GC roots may be missed, which is a much harder-to-debug problem. */
1178 get_base_file_bitmap (input_file)
1179 const char *input_file;
1181 const char *basename = get_file_basename (input_file);
1182 const char *slashpos = strchr (basename, '/');
1190 for (i = 1; i < NUM_BASE_FILES; i++)
1191 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1192 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1194 /* It's in a language directory, set that language. */
1199 abort (); /* Should have found the language. */
1202 /* If it's in any config-lang.in, then set for the languages
1207 for (j = 0; j < NUM_LANG_FILES; j++)
1209 if (!strcmp(input_file, lang_files[j]))
1211 for (k = 0; k < NUM_BASE_FILES; k++)
1213 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1219 /* Otherwise, set all languages. */
1221 bitmap = (1 << NUM_BASE_FILES) - 1;
1226 /* An output file, suitable for definitions, that can see declarations
1227 made in INPUT_FILE and is linked into every language that uses
1231 get_output_file_with_visibility (input_file)
1232 const char *input_file;
1236 const char *basename;
1237 const char *for_name;
1238 const char *output_name;
1240 /* This can happen when we need a file with visibility on a
1241 structure that we've never seen. We have to just hope that it's
1242 globally visible. */
1243 if (input_file == NULL)
1244 input_file = "system.h";
1246 /* Determine the output file name. */
1247 basename = get_file_basename (input_file);
1249 len = strlen (basename);
1250 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1251 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1252 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1256 output_name = s = xasprintf ("gt-%s", basename);
1257 for (; *s != '.'; s++)
1258 if (! ISALNUM (*s) && *s != '-')
1260 memcpy (s, ".h", sizeof (".h"));
1261 for_name = basename;
1263 else if (strcmp (basename, "c-common.h") == 0)
1264 output_name = "gt-c-common.h", for_name = "c-common.c";
1265 else if (strcmp (basename, "c-tree.h") == 0)
1266 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1271 for (i = 0; i < NUM_BASE_FILES; i++)
1272 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1273 && basename[strlen(lang_dir_names[i])] == '/')
1274 return base_files[i];
1276 output_name = "gtype-desc.c";
1280 /* Look through to see if we've ever seen this output filename before. */
1281 for (r = output_files; r; r = r->next)
1282 if (strcmp (r->name, output_name) == 0)
1285 /* If not, create it. */
1286 r = create_file (for_name, output_name);
1291 /* The name of an output file, suitable for definitions, that can see
1292 declarations made in INPUT_FILE and is linked into every language
1293 that uses INPUT_FILE. */
1296 get_output_file_name (input_file)
1297 const char *input_file;
1299 return get_output_file_with_visibility (input_file)->name;
1302 /* Copy the output to its final destination,
1303 but don't unnecessarily change modification times. */
1305 static void close_output_files PARAMS ((void));
1308 close_output_files ()
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 PARAMS ((type_p f, const struct walk_type_data *p));
1370 typedef void (*func_name_fn)
1371 PARAMS ((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 PARAMS ((struct walk_type_data *d,
1386 const char *, const char *));
1387 static void output_mangled_typename PARAMS ((outf_p, type_p));
1388 static void walk_type PARAMS ((type_p t, struct walk_type_data *d));
1389 static void write_func_for_structure
1390 PARAMS ((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 PARAMS ((type_p f, const struct walk_type_data *d));
1394 static void write_types PARAMS ((type_p structures,
1395 type_p param_structs,
1396 const struct write_types_data *wtd));
1397 static void write_types_local_process_field
1398 PARAMS ((type_p f, const struct walk_type_data *d));
1399 static void write_local_func_for_structure
1400 PARAMS ((type_p orig_s, type_p s, type_p * param));
1401 static void write_local PARAMS ((type_p structures,
1402 type_p param_structs));
1403 static void write_enum_defn PARAMS ((type_p structures, type_p param_structs));
1404 static int contains_scalar_p PARAMS ((type_p t));
1405 static void put_mangled_filename PARAMS ((outf_p , const char *));
1406 static void finish_root_table PARAMS ((struct flist *flp, const char *pfx,
1407 const char *tname, const char *lastname,
1409 static void write_root PARAMS ((outf_p , pair_p, type_p, const char *, int,
1410 struct fileloc *, const char *));
1411 static void write_array PARAMS ((outf_p f, pair_p v,
1412 const struct write_types_data *wtd));
1413 static void write_roots PARAMS ((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;
1435 /* Print a mangled name representing T to OF. */
1438 output_mangled_typename (of, 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 (d, param, oname)
1482 struct walk_type_data *d;
1488 for (p = param; *p; p++)
1490 oprintf (d->of, "%c", *p);
1494 oprintf (d->of, "(%s)", d->prev_val[2]);
1497 oprintf (d->of, "(%s)", d->prev_val[0]);
1500 oprintf (d->of, "(%s)", d->prev_val[1]);
1504 const char *pp = d->val + strlen (d->val);
1505 while (pp[-1] == ']')
1508 oprintf (d->of, "%s", pp);
1512 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1517 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1518 which is of type T. Write code to D->OF to constrain execution (at
1519 the point that D->PROCESS_FIELD is called) to the appropriate
1520 cases. D->PREV_VAL lists the objects containing the current object,
1521 D->OPT is a list of options to apply, D->INDENT is the current
1522 indentation level, D->LINE is used to print error messages,
1523 D->BITMAP indicates which languages to print the structure for, and
1524 D->PARAM is the current parameter (from an enclosing param_is
1530 struct walk_type_data *d;
1532 const char *length = NULL;
1533 const char *desc = NULL;
1534 int maybe_undef_p = 0;
1535 int use_param_num = -1;
1536 int use_params_p = 0;
1537 int needs_cast_p = 0;
1540 for (oo = d->opt; oo; oo = oo->next)
1541 if (strcmp (oo->name, "length") == 0)
1542 length = (const char *)oo->info;
1543 else if (strcmp (oo->name, "maybe_undef") == 0)
1545 else if (strncmp (oo->name, "use_param", 9) == 0
1546 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1547 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1548 else if (strcmp (oo->name, "use_params") == 0)
1550 else if (strcmp (oo->name, "desc") == 0)
1551 desc = (const char *)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 needs_cast_p = (t->kind != TYPE_POINTER
1607 && nt->kind == TYPE_POINTER);
1611 error_at_line (d->line, "no parameter defined for `%s'",
1616 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1618 error_at_line (d->line,
1619 "field `%s' has invalid option `maybe_undef_p'\n",
1628 d->process_field (t, d);
1634 && t->u.p->u.s.line.file == NULL)
1636 oprintf (d->of, "%*sif (%s) abort();\n", d->indent, "", d->val);
1642 if (! UNION_OR_STRUCT_P (t->u.p)
1643 && t->u.p->kind != TYPE_PARAM_STRUCT)
1645 error_at_line (d->line,
1646 "field `%s' is pointer to unimplemented type",
1651 d->process_field (t->u.p, d);
1655 int loopcounter = d->counter++;
1656 const char *oldval = d->val;
1657 const char *oldprevval3 = d->prev_val[3];
1660 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1662 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1663 d->process_field(t, d);
1664 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1665 loopcounter, loopcounter);
1666 output_escaped_param (d, length, "length");
1667 oprintf (d->of, "); i%d++) {\n", loopcounter);
1669 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1671 d->prev_val[3] = oldval;
1672 walk_type (t->u.p, d);
1675 d->prev_val[3] = oldprevval3;
1678 oprintf (d->of, "%*s}\n", d->indent, "");
1680 oprintf (d->of, "%*s}\n", d->indent, "");
1687 int loopcounter = d->counter++;
1688 const char *oldval = d->val;
1691 /* If it's an array of scalars, we optimise by not generating
1693 if (t->u.a.p->kind == TYPE_SCALAR)
1696 oprintf (d->of, "%*s{\n", d->indent, "");
1698 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1699 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1700 loopcounter, loopcounter);
1702 output_escaped_param (d, length, "length");
1704 oprintf (d->of, "%s", t->u.a.len);
1705 oprintf (d->of, "); i%d++) {\n", loopcounter);
1707 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1709 walk_type (t->u.a.p, d);
1714 oprintf (d->of, "%*s}\n", d->indent, "");
1716 oprintf (d->of, "%*s}\n", d->indent, "");
1724 const char *oldval = d->val;
1725 const char *oldprevval1 = d->prev_val[1];
1726 const char *oldprevval2 = d->prev_val[2];
1727 const int union_p = t->kind == TYPE_UNION;
1728 int seen_default_p = 0;
1731 if (! t->u.s.line.file)
1732 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1734 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1736 error_at_line (d->line,
1737 "structure `%s' defined for mismatching languages",
1739 error_at_line (&t->u.s.line, "one structure defined here");
1742 /* Some things may also be defined in the structure's options. */
1743 for (o = t->u.s.opt; o; o = o->next)
1744 if (! desc && strcmp (o->name, "desc") == 0)
1745 desc = (const char *)o->info;
1747 d->prev_val[2] = oldval;
1748 d->prev_val[1] = oldprevval2;
1753 error_at_line (d->line, "missing `desc' option for union `%s'",
1757 oprintf (d->of, "%*sswitch (", d->indent, "");
1758 output_escaped_param (d, desc, "desc");
1759 oprintf (d->of, ")\n");
1761 oprintf (d->of, "%*s{\n", d->indent, "");
1763 for (f = t->u.s.fields; f; f = f->next)
1766 const char *dot = ".";
1767 const char *tagid = NULL;
1770 int use_param_p = 0;
1773 d->reorder_fn = NULL;
1774 for (oo = f->opt; oo; oo = oo->next)
1775 if (strcmp (oo->name, "dot") == 0)
1776 dot = (const char *)oo->info;
1777 else if (strcmp (oo->name, "tag") == 0)
1778 tagid = (const char *)oo->info;
1779 else if (strcmp (oo->name, "skip") == 0)
1781 else if (strcmp (oo->name, "default") == 0)
1783 else if (strcmp (oo->name, "reorder") == 0)
1784 d->reorder_fn = (const char *)oo->info;
1785 else if (strncmp (oo->name, "use_param", 9) == 0
1786 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1792 if (union_p && tagid)
1794 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1797 else if (union_p && default_p)
1799 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1803 else if (! union_p && (default_p || tagid))
1804 error_at_line (d->line,
1805 "can't use `%s' outside a union on field `%s'",
1806 default_p ? "default" : "tag", f->name);
1807 else if (union_p && ! (default_p || tagid)
1808 && f->type->kind == TYPE_SCALAR)
1811 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1812 d->line->file, d->line->line, f->name);
1815 else if (union_p && ! (default_p || tagid))
1816 error_at_line (d->line,
1817 "field `%s' is missing `tag' or `default' option",
1821 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1824 if (union_p && use_param_p && d->param == NULL)
1825 oprintf (d->of, "%*sabort();\n", d->indent, "");
1827 walk_type (f->type, d);
1833 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1837 d->reorder_fn = NULL;
1840 d->prev_val[1] = oldprevval1;
1841 d->prev_val[2] = oldprevval2;
1843 if (union_p && ! seen_default_p)
1845 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1846 oprintf (d->of, "%*s break;\n", d->indent, "");
1850 oprintf (d->of, "%*s}\n", d->indent, "");
1856 case TYPE_LANG_STRUCT:
1859 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1860 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1863 error_at_line (d->line, "structure `%s' differs between languages",
1870 case TYPE_PARAM_STRUCT:
1872 type_p *oldparam = d->param;
1874 d->param = t->u.param_struct.param;
1875 walk_type (t->u.param_struct.stru, d);
1876 d->param = oldparam;
1885 /* process_field routine for marking routines. */
1888 write_types_process_field (f, d)
1890 const struct walk_type_data *d;
1892 const struct write_types_data *wtd;
1893 wtd = (const struct write_types_data *) d->cookie;
1898 oprintf (d->of, "%*s%s (%s", d->indent, "",
1899 wtd->subfield_marker_routine, d->val);
1900 if (wtd->param_prefix)
1902 oprintf (d->of, ", %s", d->prev_val[3]);
1905 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1906 output_mangled_typename (d->of, d->orig_s);
1909 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1911 oprintf (d->of, ");\n");
1912 if (d->reorder_fn && wtd->reorder_note_routine)
1913 oprintf (d->of, "%*s%s (%s, %s, %s);\n", d->indent, "",
1914 wtd->reorder_note_routine, d->val,
1915 d->prev_val[3], d->reorder_fn);
1919 if (wtd->param_prefix == NULL)
1924 case TYPE_LANG_STRUCT:
1925 case TYPE_PARAM_STRUCT:
1926 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1927 output_mangled_typename (d->of, f);
1928 oprintf (d->of, " (%s);\n", d->val);
1929 if (d->reorder_fn && wtd->reorder_note_routine)
1930 oprintf (d->of, "%*s%s (%s, %s, %s);\n", d->indent, "",
1931 wtd->reorder_note_routine, d->val, d->val,
1943 /* For S, a structure that's part of ORIG_S, and using parameters
1944 PARAM, write out a routine that:
1945 - Takes a parameter, a void * but actually of type *S
1946 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1947 field of S or its substructures and (in some cases) things
1948 that are pointed to by S.
1952 write_func_for_structure (orig_s, s, param, wtd)
1956 const struct write_types_data *wtd;
1958 const char *fn = s->u.s.line.file;
1960 const char *chain_next = NULL;
1961 const char *chain_prev = NULL;
1963 struct walk_type_data d;
1965 /* This is a hack, and not the good kind either. */
1966 for (i = NUM_PARAM - 1; i >= 0; i--)
1967 if (param && param[i] && param[i]->kind == TYPE_POINTER
1968 && UNION_OR_STRUCT_P (param[i]->u.p))
1969 fn = param[i]->u.p->u.s.line.file;
1971 memset (&d, 0, sizeof (d));
1972 d.of = get_output_file_with_visibility (fn);
1974 for (opt = s->u.s.opt; opt; opt = opt->next)
1975 if (strcmp (opt->name, "chain_next") == 0)
1976 chain_next = (const char *) opt->info;
1977 else if (strcmp (opt->name, "chain_prev") == 0)
1978 chain_prev = (const char *) opt->info;
1980 if (chain_prev != NULL && chain_next == NULL)
1981 error_at_line (&s->u.s.line, "chain_prev without chain_next");
1983 d.process_field = write_types_process_field;
1987 d.line = &s->u.s.line;
1988 d.bitmap = s->u.s.bitmap;
1990 d.prev_val[0] = "*x";
1991 d.prev_val[1] = "not valid postage"; /* guarantee an error */
1992 d.prev_val[3] = "x";
1995 oprintf (d.of, "\n");
1996 oprintf (d.of, "void\n");
1998 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2001 oprintf (d.of, "gt_%s_", wtd->prefix);
2002 output_mangled_typename (d.of, orig_s);
2004 oprintf (d.of, " (x_p)\n");
2005 oprintf (d.of, " void *x_p;\n");
2006 oprintf (d.of, "{\n");
2007 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2008 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2009 chain_next == NULL ? "const " : "",
2010 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2011 if (chain_next != NULL)
2012 oprintf (d.of, " %s %s * xlimit = x;\n",
2013 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2014 if (chain_next == NULL)
2016 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2017 if (wtd->param_prefix)
2019 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2020 output_mangled_typename (d.of, orig_s);
2022 oprintf (d.of, "))\n");
2026 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2027 if (wtd->param_prefix)
2029 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2030 output_mangled_typename (d.of, orig_s);
2032 oprintf (d.of, "))\n");
2033 oprintf (d.of, " xlimit = (");
2034 d.prev_val[2] = "*xlimit";
2035 output_escaped_param (&d, chain_next, "chain_next");
2036 oprintf (d.of, ");\n");
2037 if (chain_prev != NULL)
2039 oprintf (d.of, " if (x != xlimit)\n");
2040 oprintf (d.of, " for (;;)\n");
2041 oprintf (d.of, " {\n");
2042 oprintf (d.of, " %s %s * const xprev = (",
2043 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2045 d.prev_val[2] = "*x";
2046 output_escaped_param (&d, chain_prev, "chain_prev");
2047 oprintf (d.of, ");\n");
2048 oprintf (d.of, " if (xprev == NULL) break;\n");
2049 oprintf (d.of, " x = xprev;\n");
2050 oprintf (d.of, " (void) %s (xprev",
2051 wtd->marker_routine);
2052 if (wtd->param_prefix)
2054 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2055 output_mangled_typename (d.of, orig_s);
2057 oprintf (d.of, ");\n");
2058 oprintf (d.of, " }\n");
2060 oprintf (d.of, " while (x != xlimit)\n");
2062 oprintf (d.of, " {\n");
2064 d.prev_val[2] = "*x";
2068 if (chain_next != NULL)
2070 oprintf (d.of, " x = (");
2071 output_escaped_param (&d, chain_next, "chain_next");
2072 oprintf (d.of, ");\n");
2075 oprintf (d.of, " }\n");
2076 oprintf (d.of, "}\n");
2079 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2082 write_types (structures, param_structs, wtd)
2084 type_p param_structs;
2085 const struct write_types_data *wtd;
2089 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2090 for (s = structures; s; s = s->next)
2091 if (s->gc_used == GC_POINTED_TO
2092 || s->gc_used == GC_MAYBE_POINTED_TO)
2096 if (s->gc_used == GC_MAYBE_POINTED_TO
2097 && s->u.s.line.file == NULL)
2100 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2101 output_mangled_typename (header_file, s);
2102 oprintf (header_file, "(X) do { \\\n");
2103 oprintf (header_file,
2104 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2106 oprintf (header_file,
2109 for (opt = s->u.s.opt; opt; opt = opt->next)
2110 if (strcmp (opt->name, "ptr_alias") == 0)
2112 type_p t = (type_p) opt->info;
2113 if (t->kind == TYPE_STRUCT
2114 || t->kind == TYPE_UNION
2115 || t->kind == TYPE_LANG_STRUCT)
2116 oprintf (header_file,
2117 "#define gt_%sx_%s gt_%sx_%s\n",
2118 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2120 error_at_line (&s->u.s.line,
2121 "structure alias is not a structure");
2127 /* Declare the marker procedure only once. */
2128 oprintf (header_file,
2129 "extern void gt_%sx_%s PARAMS ((void *));\n",
2130 wtd->prefix, s->u.s.tag);
2132 if (s->u.s.line.file == NULL)
2134 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2139 if (s->kind == TYPE_LANG_STRUCT)
2142 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2143 write_func_for_structure (s, ss, NULL, wtd);
2146 write_func_for_structure (s, s, NULL, wtd);
2149 for (s = param_structs; s; s = s->next)
2150 if (s->gc_used == GC_POINTED_TO)
2152 type_p * param = s->u.param_struct.param;
2153 type_p stru = s->u.param_struct.stru;
2155 /* Declare the marker procedure. */
2156 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2157 output_mangled_typename (header_file, s);
2158 oprintf (header_file, " PARAMS ((void *));\n");
2160 if (stru->u.s.line.file == NULL)
2162 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2167 if (stru->kind == TYPE_LANG_STRUCT)
2170 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2171 write_func_for_structure (s, ss, param, wtd);
2174 write_func_for_structure (s, stru, param, wtd);
2178 static const struct write_types_data ggc_wtd =
2180 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2181 "GC marker procedures. "
2184 static const struct write_types_data pch_wtd =
2186 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2187 "gt_pch_note_reorder",
2188 "PCH type-walking procedures. "
2191 /* Write out the local pointer-walking routines. */
2193 /* process_field routine for local pointer-walking. */
2196 write_types_local_process_field (f, d)
2198 const struct walk_type_data *d;
2205 case TYPE_LANG_STRUCT:
2206 case TYPE_PARAM_STRUCT:
2208 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2210 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2221 /* For S, a structure that's part of ORIG_S, and using parameters
2222 PARAM, write out a routine that:
2223 - Is of type gt_note_pointers
2224 - If calls PROCESS_FIELD on each field of S or its substructures.
2228 write_local_func_for_structure (orig_s, s, param)
2233 const char *fn = s->u.s.line.file;
2235 struct walk_type_data d;
2237 /* This is a hack, and not the good kind either. */
2238 for (i = NUM_PARAM - 1; i >= 0; i--)
2239 if (param && param[i] && param[i]->kind == TYPE_POINTER
2240 && UNION_OR_STRUCT_P (param[i]->u.p))
2241 fn = param[i]->u.p->u.s.line.file;
2243 memset (&d, 0, sizeof (d));
2244 d.of = get_output_file_with_visibility (fn);
2246 d.process_field = write_types_local_process_field;
2248 d.line = &s->u.s.line;
2249 d.bitmap = s->u.s.bitmap;
2251 d.prev_val[0] = d.prev_val[2] = "*x";
2252 d.prev_val[1] = "not valid postage"; /* guarantee an error */
2253 d.prev_val[3] = "x";
2256 oprintf (d.of, "\n");
2257 oprintf (d.of, "void\n");
2258 oprintf (d.of, "gt_pch_p_");
2259 output_mangled_typename (d.of, orig_s);
2260 oprintf (d.of, " (this_obj, x_p, op, cookie)\n");
2261 oprintf (d.of, " void *this_obj ATTRIBUTE_UNUSED;\n");
2262 oprintf (d.of, " void *x_p;\n");
2263 oprintf (d.of, " gt_pointer_operator op ATTRIBUTE_UNUSED;\n");
2264 oprintf (d.of, " void *cookie ATTRIBUTE_UNUSED;\n");
2265 oprintf (d.of, "{\n");
2266 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2267 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2268 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2271 oprintf (d.of, "}\n");
2274 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2277 write_local (structures, param_structs)
2279 type_p param_structs;
2283 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2284 for (s = structures; s; s = s->next)
2285 if (s->gc_used == GC_POINTED_TO
2286 || s->gc_used == GC_MAYBE_POINTED_TO)
2290 if (s->u.s.line.file == NULL)
2293 for (opt = s->u.s.opt; opt; opt = opt->next)
2294 if (strcmp (opt->name, "ptr_alias") == 0)
2296 type_p t = (type_p) opt->info;
2297 if (t->kind == TYPE_STRUCT
2298 || t->kind == TYPE_UNION
2299 || t->kind == TYPE_LANG_STRUCT)
2301 oprintf (header_file, "#define gt_pch_p_");
2302 output_mangled_typename (header_file, s);
2303 oprintf (header_file, " gt_pch_p_");
2304 output_mangled_typename (header_file, t);
2305 oprintf (header_file, "\n");
2308 error_at_line (&s->u.s.line,
2309 "structure alias is not a structure");
2315 /* Declare the marker procedure only once. */
2316 oprintf (header_file, "extern void gt_pch_p_");
2317 output_mangled_typename (header_file, s);
2318 oprintf (header_file,
2319 "\n PARAMS ((void *, void *, gt_pointer_operator, void *));\n");
2321 if (s->kind == TYPE_LANG_STRUCT)
2324 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2325 write_local_func_for_structure (s, ss, NULL);
2328 write_local_func_for_structure (s, s, NULL);
2331 for (s = param_structs; s; s = s->next)
2332 if (s->gc_used == GC_POINTED_TO)
2334 type_p * param = s->u.param_struct.param;
2335 type_p stru = s->u.param_struct.stru;
2337 /* Declare the marker procedure. */
2338 oprintf (header_file, "extern void gt_pch_p_");
2339 output_mangled_typename (header_file, s);
2340 oprintf (header_file,
2341 "\n PARAMS ((void *, void *, gt_pointer_operator, void *));\n");
2343 if (stru->u.s.line.file == NULL)
2345 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2350 if (stru->kind == TYPE_LANG_STRUCT)
2353 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2354 write_local_func_for_structure (s, ss, param);
2357 write_local_func_for_structure (s, stru, param);
2361 /* Write out the 'enum' definition for gt_types_enum. */
2364 write_enum_defn (structures, param_structs)
2366 type_p param_structs;
2370 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2371 oprintf (header_file, "enum gt_types_enum {\n");
2372 for (s = structures; s; s = s->next)
2373 if (s->gc_used == GC_POINTED_TO
2374 || s->gc_used == GC_MAYBE_POINTED_TO)
2376 if (s->gc_used == GC_MAYBE_POINTED_TO
2377 && s->u.s.line.file == NULL)
2380 oprintf (header_file, " gt_ggc_e_");
2381 output_mangled_typename (header_file, s);
2382 oprintf (header_file, ", \n");
2384 for (s = param_structs; s; s = s->next)
2385 if (s->gc_used == GC_POINTED_TO)
2387 oprintf (header_file, " gt_e_");
2388 output_mangled_typename (header_file, s);
2389 oprintf (header_file, ", \n");
2391 oprintf (header_file, " gt_types_enum_last\n");
2392 oprintf (header_file, "};\n");
2395 /* Might T contain any non-pointer elements? */
2398 contains_scalar_p (t)
2407 return contains_scalar_p (t->u.a.p);
2409 /* Could also check for structures that have no non-pointer
2410 fields, but there aren't enough of those to worry about. */
2415 /* Mangle FN and print it to F. */
2418 put_mangled_filename (f, fn)
2422 const char *name = get_output_file_name (fn);
2423 for (; *name != 0; name++)
2424 if (ISALNUM (*name))
2425 oprintf (f, "%c", *name);
2427 oprintf (f, "%c", '_');
2430 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2431 LASTNAME, and NAME are all strings to insert in various places in
2432 the resulting code. */
2435 finish_root_table (flp, pfx, lastname, tname, name)
2439 const char *lastname;
2444 for (fli2 = flp; fli2; fli2 = fli2->next)
2445 if (fli2->started_p)
2447 oprintf (fli2->f, " %s\n", lastname);
2448 oprintf (fli2->f, "};\n\n");
2451 for (fli2 = flp; fli2; fli2 = fli2->next)
2452 if (fli2->started_p)
2454 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2457 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2460 oprintf (base_files[fnum],
2461 "extern const struct %s gt_%s_",
2463 put_mangled_filename (base_files[fnum], fli2->name);
2464 oprintf (base_files[fnum], "[];\n");
2470 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2471 oprintf (base_files [fnum],
2472 "const struct %s * const %s[] = {\n",
2477 for (fli2 = flp; fli2; fli2 = fli2->next)
2478 if (fli2->started_p)
2480 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2483 fli2->started_p = 0;
2485 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2488 oprintf (base_files[fnum], " gt_%s_", pfx);
2489 put_mangled_filename (base_files[fnum], fli2->name);
2490 oprintf (base_files[fnum], ",\n");
2496 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2498 oprintf (base_files[fnum], " NULL\n");
2499 oprintf (base_files[fnum], "};\n");
2504 /* Write out to F the table entry and any marker routines needed to
2505 mark NAME as TYPE. The original variable is V, at LINE.
2506 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2507 is nonzero iff we are building the root table for hash table caches. */
2510 write_root (f, v, type, name, has_length, line, if_marked)
2516 struct fileloc *line;
2517 const char *if_marked;
2524 for (fld = type->u.s.fields; fld; fld = fld->next)
2527 const char *desc = NULL;
2530 for (o = fld->opt; o; o = o->next)
2531 if (strcmp (o->name, "skip") == 0)
2533 else if (strcmp (o->name, "desc") == 0)
2534 desc = (const char *)o->info;
2536 error_at_line (line,
2537 "field `%s' of global `%s' has unknown option `%s'",
2538 fld->name, name, o->name);
2542 else if (desc && fld->type->kind == TYPE_UNION)
2544 pair_p validf = NULL;
2547 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2549 const char *tag = NULL;
2552 for (oo = ufld->opt; oo; oo = oo->next)
2553 if (strcmp (oo->name, "tag") == 0)
2554 tag = (const char *)oo->info;
2555 if (tag == NULL || strcmp (tag, desc) != 0)
2558 error_at_line (line,
2559 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2560 name, fld->name, validf->name,
2561 name, fld->name, ufld->name,
2568 newname = xasprintf ("%s.%s.%s",
2569 name, fld->name, validf->name);
2570 write_root (f, v, validf->type, newname, 0, line,
2576 error_at_line (line,
2577 "global `%s.%s' has `desc' option but is not union",
2582 newname = xasprintf ("%s.%s", name, fld->name);
2583 write_root (f, v, fld->type, newname, 0, line, if_marked);
2593 newname = xasprintf ("%s[0]", name);
2594 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2603 oprintf (f, " {\n");
2604 oprintf (f, " &%s,\n", name);
2607 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2609 oprintf (f, " * (%s)", ap->u.a.len);
2610 else if (ap == v->type)
2611 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2613 oprintf (f, " sizeof (%s", v->name);
2614 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2616 oprintf (f, "),\n");
2620 if (! has_length && UNION_OR_STRUCT_P (tp))
2622 oprintf (f, " >_ggc_mx_%s,\n", tp->u.s.tag);
2623 oprintf (f, " >_pch_nx_%s", tp->u.s.tag);
2625 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2627 oprintf (f, " >_ggc_m_");
2628 output_mangled_typename (f, tp);
2629 oprintf (f, ",\n >_pch_n_");
2630 output_mangled_typename (f, tp);
2633 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2635 oprintf (f, " >_ggc_ma_%s,\n", name);
2636 oprintf (f, " >_pch_na_%s", name);
2640 error_at_line (line,
2641 "global `%s' is pointer to unimplemented type",
2645 oprintf (f, ",\n &%s", if_marked);
2646 oprintf (f, "\n },\n");
2652 oprintf (f, " {\n");
2653 oprintf (f, " &%s,\n", name);
2654 oprintf (f, " 1, \n");
2655 oprintf (f, " sizeof (%s),\n", v->name);
2656 oprintf (f, " >_ggc_m_S,\n");
2657 oprintf (f, " >_pch_n_S\n");
2658 oprintf (f, " },\n");
2666 error_at_line (line,
2667 "global `%s' is unimplemented type",
2672 /* This generates a routine to walk an array. */
2675 write_array (f, v, wtd)
2678 const struct write_types_data *wtd;
2680 struct walk_type_data d;
2683 memset (&d, 0, sizeof (d));
2689 d.bitmap = get_base_file_bitmap (v->line.file);
2692 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2694 if (wtd->param_prefix)
2696 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2698 " PARAMS ((void *, void *, gt_pointer_operator, void *));\n");
2699 oprintf (f, "static void gt_%sa_%s (this_obj, x_p, op, cookie)\n",
2700 wtd->param_prefix, v->name);
2701 oprintf (d.of, " void *this_obj ATTRIBUTE_UNUSED;\n");
2702 oprintf (d.of, " void *x_p ATTRIBUTE_UNUSED;\n");
2703 oprintf (d.of, " gt_pointer_operator op ATTRIBUTE_UNUSED;\n");
2704 oprintf (d.of, " void *cookie ATTRIBUTE_UNUSED;\n");
2705 oprintf (d.of, "{\n");
2706 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2707 d.process_field = write_types_local_process_field;
2708 walk_type (v->type, &d);
2709 oprintf (f, "}\n\n");
2713 oprintf (f, "static void gt_%sa_%s PARAMS ((void *));\n",
2714 wtd->prefix, v->name);
2715 oprintf (f, "static void\ngt_%sa_%s (x_p)\n",
2716 wtd->prefix, v->name);
2717 oprintf (f, " void *x_p ATTRIBUTE_UNUSED;\n");
2719 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2720 d.process_field = write_types_process_field;
2721 walk_type (v->type, &d);
2723 oprintf (f, "}\n\n");
2726 /* Output a table describing the locations and types of VARIABLES. */
2729 write_roots (variables)
2733 struct flist *flp = NULL;
2735 for (v = variables; v; v = v->next)
2737 outf_p f = get_output_file_with_visibility (v->line.file);
2739 const char *length = NULL;
2740 int deletable_p = 0;
2743 for (o = v->opt; o; o = o->next)
2744 if (strcmp (o->name, "length") == 0)
2745 length = (const char *)o->info;
2746 else if (strcmp (o->name, "deletable") == 0)
2748 else if (strcmp (o->name, "param_is") == 0)
2750 else if (strncmp (o->name, "param", 5) == 0
2751 && ISDIGIT (o->name[5])
2752 && strcmp (o->name + 6, "_is") == 0)
2754 else if (strcmp (o->name, "if_marked") == 0)
2757 error_at_line (&v->line,
2758 "global `%s' has unknown option `%s'",
2761 for (fli = flp; fli; fli = fli->next)
2766 fli = xmalloc (sizeof (*fli));
2770 fli->name = v->line.file;
2773 oprintf (f, "\n/* GC roots. */\n\n");
2778 && v->type->kind == TYPE_POINTER
2779 && (v->type->u.p->kind == TYPE_POINTER
2780 || v->type->u.p->kind == TYPE_STRUCT))
2782 write_array (f, v, &ggc_wtd);
2783 write_array (f, v, &pch_wtd);
2787 for (v = variables; v; v = v->next)
2789 outf_p f = get_output_file_with_visibility (v->line.file);
2795 for (o = v->opt; o; o = o->next)
2796 if (strcmp (o->name, "length") == 0)
2798 else if (strcmp (o->name, "deletable") == 0
2799 || strcmp (o->name, "if_marked") == 0)
2805 for (fli = flp; fli; fli = fli->next)
2808 if (! fli->started_p)
2812 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2813 put_mangled_filename (f, v->line.file);
2814 oprintf (f, "[] = {\n");
2817 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2820 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2823 for (v = variables; v; v = v->next)
2825 outf_p f = get_output_file_with_visibility (v->line.file);
2830 for (o = v->opt; o; o = o->next)
2831 if (strcmp (o->name, "deletable") == 0)
2833 else if (strcmp (o->name, "if_marked") == 0)
2839 for (fli = flp; fli; fli = fli->next)
2842 if (! fli->started_p)
2846 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2847 put_mangled_filename (f, v->line.file);
2848 oprintf (f, "[] = {\n");
2851 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2855 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2856 "gt_ggc_deletable_rtab");
2858 for (v = variables; v; v = v->next)
2860 outf_p f = get_output_file_with_visibility (v->line.file);
2862 const char *if_marked = NULL;
2866 for (o = v->opt; o; o = o->next)
2867 if (strcmp (o->name, "length") == 0)
2869 else if (strcmp (o->name, "if_marked") == 0)
2870 if_marked = (const char *) o->info;
2872 if (if_marked == NULL)
2875 if (v->type->kind != TYPE_POINTER
2876 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2877 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2879 error_at_line (&v->line, "if_marked option used but not hash table");
2883 for (fli = flp; fli; fli = fli->next)
2886 if (! fli->started_p)
2890 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2891 put_mangled_filename (f, v->line.file);
2892 oprintf (f, "[] = {\n");
2895 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2896 v->name, length_p, &v->line, if_marked);
2899 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2900 "gt_ggc_cache_rtab");
2902 for (v = variables; v; v = v->next)
2904 outf_p f = get_output_file_with_visibility (v->line.file);
2907 int if_marked_p = 0;
2910 for (o = v->opt; o; o = o->next)
2911 if (strcmp (o->name, "length") == 0)
2913 else if (strcmp (o->name, "if_marked") == 0)
2919 for (fli = flp; fli; fli = fli->next)
2922 if (! fli->started_p)
2926 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2927 put_mangled_filename (f, v->line.file);
2928 oprintf (f, "[] = {\n");
2931 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2934 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2935 "gt_pch_cache_rtab");
2937 for (v = variables; v; v = v->next)
2939 outf_p f = get_output_file_with_visibility (v->line.file);
2944 for (o = v->opt; o; o = o->next)
2945 if (strcmp (o->name, "deletable") == 0
2946 || strcmp (o->name, "if_marked") == 0)
2952 if (! contains_scalar_p (v->type))
2955 for (fli = flp; fli; fli = fli->next)
2958 if (! fli->started_p)
2962 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2963 put_mangled_filename (f, v->line.file);
2964 oprintf (f, "[] = {\n");
2967 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2971 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2972 "gt_pch_scalar_rtab");
2976 extern int main PARAMS ((int argc, char **argv));
2979 int argc ATTRIBUTE_UNUSED;
2980 char **argv ATTRIBUTE_UNUSED;
2983 static struct fileloc pos = { __FILE__, __LINE__ };
2988 srcdir_len = strlen (srcdir);
2990 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
2991 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
2992 do_scalar_typedef ("uint8", &pos);
2993 do_scalar_typedef ("jword", &pos);
2994 do_scalar_typedef ("JCF_u2", &pos);
2996 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
2999 do_typedef ("HARD_REG_SET", create_array (
3000 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3003 for (i = 0; i < NUM_GT_FILES; i++)
3006 /* Omit if already seen. */
3007 for (j = 0; j < i; j++)
3009 if (!strcmp (all_files[i], all_files[j]))
3016 parse_file (all_files[i]);
3022 set_gc_used (variables);
3025 write_enum_defn (structures, param_structs);
3026 write_types (structures, param_structs, &ggc_wtd);
3027 write_types (structures, param_structs, &pch_wtd);
3028 write_local (structures, param_structs);
3029 write_roots (variables);
3031 close_output_files ();
3033 return (hit_error != 0);