* cgraphunit.c, config/arm/arm.c, config/m68k/m68k.c,
[official-gcc.git] / gcc / gengtype.c
blobf195dab2e1740c0f4b6cc1b7e3a63a87fe40f72d
1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
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
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA. */
21 #include "bconfig.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "gengtype.h"
26 #include "gtyp-gen.h"
27 #include "errors.h"
29 /* Nonzero iff an error has occurred. */
30 static int hit_error = 0;
32 static void gen_rtx_next (void);
33 static void write_rtx_next (void);
34 static void open_base_files (void);
35 static void close_output_files (void);
37 /* Report an error at POS, printing MSG. */
39 void
40 error_at_line (struct fileloc *pos, const char *msg, ...)
42 va_list ap;
44 va_start (ap, msg);
46 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
47 vfprintf (stderr, msg, ap);
48 fputc ('\n', stderr);
49 hit_error = 1;
51 va_end (ap);
54 /* vasprintf, but produces fatal message on out-of-memory. */
55 int
56 xvasprintf (char **result, const char *format, va_list args)
58 int ret = vasprintf (result, format, args);
59 if (*result == NULL || ret < 0)
61 fputs ("gengtype: out of memory", stderr);
62 xexit (1);
64 return ret;
67 /* Wrapper for xvasprintf. */
68 char *
69 xasprintf (const char *format, ...)
71 char *result;
72 va_list ap;
74 va_start (ap, format);
75 xvasprintf (&result, format, ap);
76 va_end (ap);
77 return result;
80 /* The one and only TYPE_STRING. */
82 struct type string_type = {
83 TYPE_STRING, NULL, NULL, GC_USED, {0}
86 /* Lists of various things. */
88 static pair_p typedefs;
89 static type_p structures;
90 static type_p param_structs;
91 static pair_p variables;
93 static void do_scalar_typedef (const char *, struct fileloc *);
94 static type_p find_param_structure
95 (type_p t, type_p param[NUM_PARAM]);
96 static type_p adjust_field_tree_exp (type_p t, options_p opt);
97 static type_p adjust_field_rtx_def (type_p t, options_p opt);
99 /* Define S as a typedef to T at POS. */
101 void
102 do_typedef (const char *s, type_p t, struct fileloc *pos)
104 pair_p p;
106 for (p = typedefs; p != NULL; p = p->next)
107 if (strcmp (p->name, s) == 0)
109 if (p->type != t)
111 error_at_line (pos, "type `%s' previously defined", s);
112 error_at_line (&p->line, "previously defined here");
114 return;
117 p = XNEW (struct pair);
118 p->next = typedefs;
119 p->name = s;
120 p->type = t;
121 p->line = *pos;
122 typedefs = p;
125 /* Define S as a typename of a scalar. */
127 static void
128 do_scalar_typedef (const char *s, struct fileloc *pos)
130 do_typedef (s, create_scalar_type (s, strlen (s)), pos);
133 /* Return the type previously defined for S. Use POS to report errors. */
135 type_p
136 resolve_typedef (const char *s, struct fileloc *pos)
138 pair_p p;
139 for (p = typedefs; p != NULL; p = p->next)
140 if (strcmp (p->name, s) == 0)
141 return p->type;
142 error_at_line (pos, "unidentified type `%s'", s);
143 return create_scalar_type ("char", 4);
146 /* Create and return a new structure with tag NAME (or a union iff
147 ISUNION is nonzero), at POS with fields FIELDS and options O. */
149 type_p
150 new_structure (const char *name, int isunion, struct fileloc *pos,
151 pair_p fields, options_p o)
153 type_p si;
154 type_p s = NULL;
155 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
157 for (si = structures; si != NULL; si = si->next)
158 if (strcmp (name, si->u.s.tag) == 0
159 && UNION_P (si) == isunion)
161 type_p ls = NULL;
162 if (si->kind == TYPE_LANG_STRUCT)
164 ls = si;
166 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
167 if (si->u.s.bitmap == bitmap)
168 s = si;
170 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
172 ls = si;
173 si = XCNEW (struct type);
174 memcpy (si, ls, sizeof (struct type));
175 ls->kind = TYPE_LANG_STRUCT;
176 ls->u.s.lang_struct = si;
177 ls->u.s.fields = NULL;
178 si->next = NULL;
179 si->pointer_to = NULL;
180 si->u.s.lang_struct = ls;
182 else
183 s = si;
185 if (ls != NULL && s == NULL)
187 s = XCNEW (struct type);
188 s->next = ls->u.s.lang_struct;
189 ls->u.s.lang_struct = s;
190 s->u.s.lang_struct = ls;
192 break;
195 if (s == NULL)
197 s = XCNEW (struct type);
198 s->next = structures;
199 structures = s;
202 if (s->u.s.line.file != NULL
203 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
205 error_at_line (pos, "duplicate structure definition");
206 error_at_line (&s->u.s.line, "previous definition here");
209 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
210 s->u.s.tag = name;
211 s->u.s.line = *pos;
212 s->u.s.fields = fields;
213 s->u.s.opt = o;
214 s->u.s.bitmap = bitmap;
215 if (s->u.s.lang_struct)
216 s->u.s.lang_struct->u.s.bitmap |= bitmap;
218 return s;
221 /* Return the previously-defined structure with tag NAME (or a union
222 iff ISUNION is nonzero), or a new empty structure or union if none
223 was defined previously. */
225 type_p
226 find_structure (const char *name, int isunion)
228 type_p s;
230 for (s = structures; s != NULL; s = s->next)
231 if (strcmp (name, s->u.s.tag) == 0
232 && UNION_P (s) == isunion)
233 return s;
235 s = XCNEW (struct type);
236 s->next = structures;
237 structures = s;
238 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
239 s->u.s.tag = name;
240 structures = s;
241 return s;
244 /* Return the previously-defined parameterized structure for structure
245 T and parameters PARAM, or a new parameterized empty structure or
246 union if none was defined previously. */
248 static type_p
249 find_param_structure (type_p t, type_p param[NUM_PARAM])
251 type_p res;
253 for (res = param_structs; res; res = res->next)
254 if (res->u.param_struct.stru == t
255 && memcmp (res->u.param_struct.param, param,
256 sizeof (type_p) * NUM_PARAM) == 0)
257 break;
258 if (res == NULL)
260 res = XCNEW (struct type);
261 res->kind = TYPE_PARAM_STRUCT;
262 res->next = param_structs;
263 param_structs = res;
264 res->u.param_struct.stru = t;
265 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
267 return res;
270 /* Return a scalar type with name NAME. */
272 type_p
273 create_scalar_type (const char *name, size_t name_len)
275 type_p r = XCNEW (struct type);
276 r->kind = TYPE_SCALAR;
277 r->u.sc = (char *) xmemdup (name, name_len, name_len + 1);
278 return r;
281 /* Return a pointer to T. */
283 type_p
284 create_pointer (type_p t)
286 if (! t->pointer_to)
288 type_p r = XCNEW (struct type);
289 r->kind = TYPE_POINTER;
290 r->u.p = t;
291 t->pointer_to = r;
293 return t->pointer_to;
296 /* Return an array of length LEN. */
298 type_p
299 create_array (type_p t, const char *len)
301 type_p v;
303 v = XCNEW (struct type);
304 v->kind = TYPE_ARRAY;
305 v->u.a.p = t;
306 v->u.a.len = len;
307 return v;
310 /* Return an options structure with name NAME and info INFO. NEXT is the
311 next option in the chain. */
313 options_p
314 create_option (options_p next, const char *name, const void *info)
316 options_p o = XNEW (struct options);
317 o->next = next;
318 o->name = name;
319 o->info = (const char*) info;
320 return o;
323 /* Add a variable named S of type T with options O defined at POS,
324 to `variables'. */
326 void
327 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
329 pair_p n;
330 n = XNEW (struct pair);
331 n->name = s;
332 n->type = t;
333 n->line = *pos;
334 n->opt = o;
335 n->next = variables;
336 variables = n;
339 /* Create a fake field with the given type and name. NEXT is the next
340 field in the chain. */
342 static pair_p
343 create_field (pair_p next, type_p type, const char *name)
345 pair_p field;
347 field = XNEW (struct pair);
348 field->next = next;
349 field->type = type;
350 field->name = name;
351 field->opt = NULL;
352 field->line.file = __FILE__;
353 field->line.line = __LINE__;
354 return field;
357 /* Like create_field, but the field is only valid when condition COND
358 is true. */
360 static pair_p
361 create_optional_field (pair_p next, type_p type, const char *name,
362 const char *cond)
364 static int id = 1;
365 pair_p union_fields, field;
366 type_p union_type;
368 /* Create a fake union type with a single nameless field of type TYPE.
369 The field has a tag of "1". This allows us to make the presence
370 of a field of type TYPE depend on some boolean "desc" being true. */
371 union_fields = create_field (NULL, type, "");
372 union_fields->opt = create_option (union_fields->opt, "dot", "");
373 union_fields->opt = create_option (union_fields->opt, "tag", "1");
374 union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
375 &lexer_line, union_fields, NULL);
377 /* Create the field and give it the new fake union type. Add a "desc"
378 tag that specifies the condition under which the field is valid. */
379 field = create_field (next, union_type, name);
380 field->opt = create_option (field->opt, "desc", cond);
381 return field;
384 /* We don't care how long a CONST_DOUBLE is. */
385 #define CONST_DOUBLE_FORMAT "ww"
386 /* We don't want to see codes that are only for generator files. */
387 #undef GENERATOR_FILE
389 enum rtx_code {
390 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
391 #include "rtl.def"
392 #undef DEF_RTL_EXPR
393 NUM_RTX_CODE
396 static const char * const rtx_name[NUM_RTX_CODE] = {
397 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
398 #include "rtl.def"
399 #undef DEF_RTL_EXPR
402 static const char * const rtx_format[NUM_RTX_CODE] = {
403 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
404 #include "rtl.def"
405 #undef DEF_RTL_EXPR
408 static int rtx_next_new[NUM_RTX_CODE];
410 /* We also need codes and names for insn notes (not register notes).
411 Note that we do *not* bias the note values here. */
412 enum insn_note {
413 #define DEF_INSN_NOTE(NAME) NAME,
414 #include "insn-notes.def"
415 #undef DEF_INSN_NOTE
417 NOTE_INSN_MAX
420 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
421 default field for line number notes. */
422 static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
423 #define DEF_INSN_NOTE(NAME) #NAME,
424 #include "insn-notes.def"
425 #undef DEF_INSN_NOTE
428 #undef CONST_DOUBLE_FORMAT
429 #define GENERATOR_FILE
431 /* Generate the contents of the rtx_next array. This really doesn't belong
432 in gengtype at all, but it's needed for adjust_field_rtx_def. */
434 static void
435 gen_rtx_next (void)
437 int i;
438 for (i = 0; i < NUM_RTX_CODE; i++)
440 int k;
442 rtx_next_new[i] = -1;
443 if (strncmp (rtx_format[i], "iuu", 3) == 0)
444 rtx_next_new[i] = 2;
445 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
446 rtx_next_new[i] = 1;
447 else
448 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
449 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
450 rtx_next_new[i] = k;
454 /* Write out the contents of the rtx_next array. */
455 static void
456 write_rtx_next (void)
458 outf_p f = get_output_file_with_visibility (NULL);
459 int i;
461 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
462 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
463 for (i = 0; i < NUM_RTX_CODE; i++)
464 if (rtx_next_new[i] == -1)
465 oprintf (f, " 0,\n");
466 else
467 oprintf (f,
468 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
469 rtx_next_new[i]);
470 oprintf (f, "};\n");
473 /* Handle `special("rtx_def")'. This is a special case for field
474 `fld' of struct rtx_def, which is an array of unions whose values
475 are based in a complex way on the type of RTL. */
477 static type_p
478 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
480 pair_p flds = NULL;
481 options_p nodot;
482 int i;
483 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
484 type_p bitmap_tp, basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
486 if (t->kind != TYPE_UNION)
488 error_at_line (&lexer_line,
489 "special `rtx_def' must be applied to a union");
490 return &string_type;
493 nodot = create_option (NULL, "dot", "");
495 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
496 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
497 tree_tp = create_pointer (find_structure ("tree_node", 1));
498 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
499 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
500 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
501 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
502 constant_tp = create_pointer (find_structure ("constant_descriptor_rtx", 0));
503 scalar_tp = create_scalar_type ("rtunion scalar", 14);
506 pair_p note_flds = NULL;
507 int c;
509 for (c = 0; c <= NOTE_INSN_MAX; c++)
511 switch (c)
513 case NOTE_INSN_MAX:
514 note_flds = create_field (note_flds, &string_type, "rt_str");
515 break;
517 case NOTE_INSN_BLOCK_BEG:
518 case NOTE_INSN_BLOCK_END:
519 note_flds = create_field (note_flds, tree_tp, "rt_tree");
520 break;
522 case NOTE_INSN_VAR_LOCATION:
523 note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
524 break;
526 default:
527 note_flds = create_field (note_flds, scalar_tp, "rt_int");
528 break;
530 /* NOTE_INSN_MAX is used as the default field for line
531 number notes. */
532 if (c == NOTE_INSN_MAX)
533 note_flds->opt = create_option (nodot, "default", "");
534 else
535 note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
537 note_union_tp = new_structure ("rtx_def_note_subunion", 1,
538 &lexer_line, note_flds, NULL);
540 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */
542 pair_p sym_flds;
544 sym_flds = create_field (NULL, tree_tp, "rt_tree");
545 sym_flds->opt = create_option (nodot, "default", "");
547 sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
548 sym_flds->opt = create_option (nodot, "tag", "1");
550 symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
551 &lexer_line, sym_flds, NULL);
553 for (i = 0; i < NUM_RTX_CODE; i++)
555 pair_p subfields = NULL;
556 size_t aindex, nmindex;
557 const char *sname;
558 type_p substruct;
559 char *ftag;
561 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
563 type_p t;
564 const char *subname;
566 switch (rtx_format[i][aindex])
568 case '*':
569 case 'i':
570 case 'n':
571 case 'w':
572 t = scalar_tp;
573 subname = "rt_int";
574 break;
576 case '0':
577 if (i == MEM && aindex == 1)
578 t = mem_attrs_tp, subname = "rt_mem";
579 else if (i == JUMP_INSN && aindex == 9)
580 t = rtx_tp, subname = "rt_rtx";
581 else if (i == CODE_LABEL && aindex == 4)
582 t = scalar_tp, subname = "rt_int";
583 else if (i == CODE_LABEL && aindex == 5)
584 t = rtx_tp, subname = "rt_rtx";
585 else if (i == LABEL_REF
586 && (aindex == 1 || aindex == 2))
587 t = rtx_tp, subname = "rt_rtx";
588 else if (i == NOTE && aindex == 4)
589 t = note_union_tp, subname = "";
590 else if (i == NOTE && aindex >= 7)
591 t = scalar_tp, subname = "rt_int";
592 else if (i == ADDR_DIFF_VEC && aindex == 4)
593 t = scalar_tp, subname = "rt_int";
594 else if (i == VALUE && aindex == 0)
595 t = scalar_tp, subname = "rt_int";
596 else if (i == REG && aindex == 1)
597 t = scalar_tp, subname = "rt_int";
598 else if (i == REG && aindex == 2)
599 t = reg_attrs_tp, subname = "rt_reg";
600 else if (i == SCRATCH && aindex == 0)
601 t = scalar_tp, subname = "rt_int";
602 else if (i == SYMBOL_REF && aindex == 1)
603 t = scalar_tp, subname = "rt_int";
604 else if (i == SYMBOL_REF && aindex == 2)
605 t = symbol_union_tp, subname = "";
606 else if (i == BARRIER && aindex >= 3)
607 t = scalar_tp, subname = "rt_int";
608 else
610 error_at_line (&lexer_line,
611 "rtx type `%s' has `0' in position %lu, can't handle",
612 rtx_name[i], (unsigned long) aindex);
613 t = &string_type;
614 subname = "rt_int";
616 break;
618 case 's':
619 case 'S':
620 case 'T':
621 t = &string_type;
622 subname = "rt_str";
623 break;
625 case 'e':
626 case 'u':
627 t = rtx_tp;
628 subname = "rt_rtx";
629 break;
631 case 'E':
632 case 'V':
633 t = rtvec_tp;
634 subname = "rt_rtvec";
635 break;
637 case 't':
638 t = tree_tp;
639 subname = "rt_tree";
640 break;
642 case 'b':
643 t = bitmap_tp;
644 subname = "rt_bit";
645 break;
647 case 'B':
648 t = basic_block_tp;
649 subname = "rt_bb";
650 break;
652 default:
653 error_at_line (&lexer_line,
654 "rtx type `%s' has `%c' in position %lu, can't handle",
655 rtx_name[i], rtx_format[i][aindex],
656 (unsigned long)aindex);
657 t = &string_type;
658 subname = "rt_int";
659 break;
662 subfields = create_field (subfields, t,
663 xasprintf (".fld[%lu].%s",
664 (unsigned long) aindex,
665 subname));
666 subfields->opt = nodot;
667 if (t == note_union_tp)
668 subfields->opt = create_option (subfields->opt, "desc",
669 "NOTE_LINE_NUMBER (&%0)");
670 if (t == symbol_union_tp)
671 subfields->opt = create_option (subfields->opt, "desc",
672 "CONSTANT_POOL_ADDRESS_P (&%0)");
675 if (i == SYMBOL_REF)
677 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
678 type_p field_tp = find_structure ("block_symbol", 0);
679 subfields
680 = create_optional_field (subfields, field_tp, "block_sym",
681 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
684 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
685 substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
687 ftag = xstrdup (rtx_name[i]);
688 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
689 ftag[nmindex] = TOUPPER (ftag[nmindex]);
691 flds = create_field (flds, substruct, "");
692 flds->opt = create_option (nodot, "tag", ftag);
695 return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
698 /* Handle `special("tree_exp")'. This is a special case for
699 field `operands' of struct tree_exp, which although it claims to contain
700 pointers to trees, actually sometimes contains pointers to RTL too.
701 Passed T, the old type of the field, and OPT its options. Returns
702 a new type for the field. */
704 static type_p
705 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
707 pair_p flds;
708 options_p nodot;
710 if (t->kind != TYPE_ARRAY)
712 error_at_line (&lexer_line,
713 "special `tree_exp' must be applied to an array");
714 return &string_type;
717 nodot = create_option (NULL, "dot", "");
719 flds = create_field (NULL, t, "");
720 flds->opt = create_option (nodot, "length",
721 "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))");
722 flds->opt = create_option (flds->opt, "default", "");
724 return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
727 /* Perform any special processing on a type T, about to become the type
728 of a field. Return the appropriate type for the field.
729 At present:
730 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
731 - Similarly for arrays of pointer-to-char;
732 - Converts structures for which a parameter is provided to
733 TYPE_PARAM_STRUCT;
734 - Handles "special" options.
737 type_p
738 adjust_field_type (type_p t, options_p opt)
740 int length_p = 0;
741 const int pointer_p = t->kind == TYPE_POINTER;
742 type_p params[NUM_PARAM];
743 int params_p = 0;
744 int i;
746 for (i = 0; i < NUM_PARAM; i++)
747 params[i] = NULL;
749 for (; opt; opt = opt->next)
750 if (strcmp (opt->name, "length") == 0)
751 length_p = 1;
752 else if (strcmp (opt->name, "param_is") == 0
753 || (strncmp (opt->name, "param", 5) == 0
754 && ISDIGIT (opt->name[5])
755 && strcmp (opt->name + 6, "_is") == 0))
757 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
759 if (! UNION_OR_STRUCT_P (t)
760 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
762 error_at_line (&lexer_line,
763 "option `%s' may only be applied to structures or structure pointers",
764 opt->name);
765 return t;
768 params_p = 1;
769 if (params[num] != NULL)
770 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
771 if (! ISDIGIT (opt->name[5]))
772 params[num] = create_pointer ((type_p) opt->info);
773 else
774 params[num] = (type_p) opt->info;
776 else if (strcmp (opt->name, "special") == 0)
778 const char *special_name = opt->info;
779 if (strcmp (special_name, "tree_exp") == 0)
780 t = adjust_field_tree_exp (t, opt);
781 else if (strcmp (special_name, "rtx_def") == 0)
782 t = adjust_field_rtx_def (t, opt);
783 else
784 error_at_line (&lexer_line, "unknown special `%s'", special_name);
787 if (params_p)
789 type_p realt;
791 if (pointer_p)
792 t = t->u.p;
793 realt = find_param_structure (t, params);
794 t = pointer_p ? create_pointer (realt) : realt;
797 if (! length_p
798 && pointer_p
799 && t->u.p->kind == TYPE_SCALAR
800 && (strcmp (t->u.p->u.sc, "char") == 0
801 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
802 return &string_type;
803 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
804 && t->u.a.p->u.p->kind == TYPE_SCALAR
805 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
806 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
807 return create_array (&string_type, t->u.a.len);
809 return t;
812 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
813 and information about the correspondence between token types and fields
814 in TYPEINFO. POS is used for error messages. */
816 void
817 note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
818 struct fileloc *pos)
820 pair_p p;
821 pair_p *p_p;
823 for (p = typeinfo; p; p = p->next)
825 pair_p m;
827 if (p->name == NULL)
828 continue;
830 if (p->type == (type_p) 1)
832 pair_p pp;
833 int ok = 0;
835 for (pp = typeinfo; pp; pp = pp->next)
836 if (pp->type != (type_p) 1
837 && strcmp (pp->opt->info, p->opt->info) == 0)
839 ok = 1;
840 break;
842 if (! ok)
843 continue;
846 for (m = fields; m; m = m->next)
847 if (strcmp (m->name, p->name) == 0)
848 p->type = m->type;
849 if (p->type == NULL)
851 error_at_line (&p->line,
852 "couldn't match fieldname `%s'", p->name);
853 p->name = NULL;
857 p_p = &typeinfo;
858 while (*p_p)
860 pair_p p = *p_p;
862 if (p->name == NULL
863 || p->type == (type_p) 1)
864 *p_p = p->next;
865 else
866 p_p = &p->next;
869 do_typedef ("YYSTYPE", new_structure ("yy_union", 1, pos, typeinfo, o), pos);
872 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
873 static void set_gc_used (pair_p);
875 /* Handle OPT for set_gc_used_type. */
877 static void
878 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
879 int *pass_param, int *length, int *skip, type_p *nested_ptr)
881 options_p o;
882 for (o = opt; o; o = o->next)
883 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
884 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
885 else if (strcmp (o->name, "maybe_undef") == 0)
886 *maybe_undef = 1;
887 else if (strcmp (o->name, "use_params") == 0)
888 *pass_param = 1;
889 else if (strcmp (o->name, "length") == 0)
890 *length = 1;
891 else if (strcmp (o->name, "skip") == 0)
892 *skip = 1;
893 else if (strcmp (o->name, "nested_ptr") == 0)
894 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
897 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
899 static void
900 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
902 if (t->gc_used >= level)
903 return;
905 t->gc_used = level;
907 switch (t->kind)
909 case TYPE_STRUCT:
910 case TYPE_UNION:
912 pair_p f;
913 int dummy;
914 type_p dummy2;
916 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
917 &dummy2);
919 for (f = t->u.s.fields; f; f = f->next)
921 int maybe_undef = 0;
922 int pass_param = 0;
923 int length = 0;
924 int skip = 0;
925 type_p nested_ptr = NULL;
926 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
927 &length, &skip, &nested_ptr);
929 if (nested_ptr && f->type->kind == TYPE_POINTER)
930 set_gc_used_type (nested_ptr, GC_POINTED_TO,
931 pass_param ? param : NULL);
932 else if (length && f->type->kind == TYPE_POINTER)
933 set_gc_used_type (f->type->u.p, GC_USED, NULL);
934 else if (maybe_undef && f->type->kind == TYPE_POINTER)
935 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
936 else if (pass_param && f->type->kind == TYPE_POINTER && param)
937 set_gc_used_type (find_param_structure (f->type->u.p, param),
938 GC_POINTED_TO, NULL);
939 else if (skip)
940 ; /* target type is not used through this field */
941 else
942 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
944 break;
947 case TYPE_POINTER:
948 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
949 break;
951 case TYPE_ARRAY:
952 set_gc_used_type (t->u.a.p, GC_USED, param);
953 break;
955 case TYPE_LANG_STRUCT:
956 for (t = t->u.s.lang_struct; t; t = t->next)
957 set_gc_used_type (t, level, param);
958 break;
960 case TYPE_PARAM_STRUCT:
962 int i;
963 for (i = 0; i < NUM_PARAM; i++)
964 if (t->u.param_struct.param[i] != 0)
965 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
967 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
968 level = GC_POINTED_TO;
969 else
970 level = GC_USED;
971 t->u.param_struct.stru->gc_used = GC_UNUSED;
972 set_gc_used_type (t->u.param_struct.stru, level,
973 t->u.param_struct.param);
974 break;
976 default:
977 break;
981 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
983 static void
984 set_gc_used (pair_p variables)
986 pair_p p;
987 for (p = variables; p; p = p->next)
988 set_gc_used_type (p->type, GC_USED, NULL);
991 /* File mapping routines. For each input file, there is one output .c file
992 (but some output files have many input files), and there is one .h file
993 for the whole build. */
995 /* The list of output files. */
996 static outf_p output_files;
998 /* The output header file that is included into pretty much every
999 source file. */
1000 static outf_p header_file;
1002 /* Number of files specified in gtfiles. */
1003 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1005 /* Number of files in the language files array. */
1006 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1008 /* Length of srcdir name. */
1009 static int srcdir_len = 0;
1011 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1012 outf_p base_files[NUM_BASE_FILES];
1014 static outf_p create_file (const char *, const char *);
1015 static const char * get_file_basename (const char *);
1017 /* Create and return an outf_p for a new file for NAME, to be called
1018 ONAME. */
1020 static outf_p
1021 create_file (const char *name, const char *oname)
1023 static const char *const hdr[] = {
1024 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
1025 "\n",
1026 "This file is part of GCC.\n",
1027 "\n",
1028 "GCC is free software; you can redistribute it and/or modify it under\n",
1029 "the terms of the GNU General Public License as published by the Free\n",
1030 "Software Foundation; either version 2, or (at your option) any later\n",
1031 "version.\n",
1032 "\n",
1033 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1034 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1035 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1036 "for more details.\n",
1037 "\n",
1038 "You should have received a copy of the GNU General Public License\n",
1039 "along with GCC; see the file COPYING. If not, write to the Free\n",
1040 "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1041 "02110-1301, USA. */\n",
1042 "\n",
1043 "/* This file is machine generated. Do not edit. */\n"
1045 outf_p f;
1046 size_t i;
1048 f = XCNEW (struct outf);
1049 f->next = output_files;
1050 f->name = oname;
1051 output_files = f;
1053 oprintf (f, "/* Type information for %s.\n", name);
1054 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1055 oprintf (f, "%s", hdr[i]);
1056 return f;
1059 /* Print, like fprintf, to O. */
1060 void
1061 oprintf (outf_p o, const char *format, ...)
1063 char *s;
1064 size_t slength;
1065 va_list ap;
1067 va_start (ap, format);
1068 slength = xvasprintf (&s, format, ap);
1070 if (o->bufused + slength > o->buflength)
1072 size_t new_len = o->buflength;
1073 if (new_len == 0)
1074 new_len = 1024;
1075 do {
1076 new_len *= 2;
1077 } while (o->bufused + slength >= new_len);
1078 o->buf = XRESIZEVEC (char, o->buf, new_len);
1079 o->buflength = new_len;
1081 memcpy (o->buf + o->bufused, s, slength);
1082 o->bufused += slength;
1083 free (s);
1084 va_end (ap);
1087 /* Open the global header file and the language-specific header files. */
1089 static void
1090 open_base_files (void)
1092 size_t i;
1094 header_file = create_file ("GCC", "gtype-desc.h");
1096 for (i = 0; i < NUM_BASE_FILES; i++)
1097 base_files[i] = create_file (lang_dir_names[i],
1098 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1100 /* gtype-desc.c is a little special, so we create it here. */
1102 /* The order of files here matters very much. */
1103 static const char *const ifiles [] = {
1104 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1105 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1106 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1107 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1108 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1109 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1110 "cfglayout.h", "except.h", "output.h", NULL
1112 const char *const *ifp;
1113 outf_p gtype_desc_c;
1115 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1116 for (ifp = ifiles; *ifp; ifp++)
1117 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1121 /* Determine the pathname to F relative to $(srcdir). */
1123 static const char *
1124 get_file_basename (const char *f)
1126 const char *basename;
1127 unsigned i;
1129 basename = strrchr (f, '/');
1131 if (!basename)
1132 return f;
1134 basename++;
1136 for (i = 1; i < NUM_BASE_FILES; i++)
1138 const char * s1;
1139 const char * s2;
1140 int l1;
1141 int l2;
1142 s1 = basename - strlen (lang_dir_names [i]) - 1;
1143 s2 = lang_dir_names [i];
1144 l1 = strlen (s1);
1145 l2 = strlen (s2);
1146 if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1148 basename -= l2 + 1;
1149 if ((basename - f - 1) != srcdir_len)
1150 fatal ("filename `%s' should be preceded by $srcdir", f);
1151 break;
1155 return basename;
1158 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1159 INPUT_FILE is used by <lang>.
1161 This function should be written to assume that a file _is_ used
1162 if the situation is unclear. If it wrongly assumes a file _is_ used,
1163 a linker error will result. If it wrongly assumes a file _is not_ used,
1164 some GC roots may be missed, which is a much harder-to-debug problem. */
1166 unsigned
1167 get_base_file_bitmap (const char *input_file)
1169 const char *basename = get_file_basename (input_file);
1170 const char *slashpos = strchr (basename, '/');
1171 unsigned j;
1172 unsigned k;
1173 unsigned bitmap;
1175 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1176 it belongs to the corresponding language. The file may belong to other
1177 languages as well (which is checked for below). */
1179 if (slashpos)
1181 size_t i;
1182 for (i = 1; i < NUM_BASE_FILES; i++)
1183 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1184 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1186 /* It's in a language directory, set that language. */
1187 bitmap = 1 << i;
1191 /* If it's in any config-lang.in, then set for the languages
1192 specified. */
1194 bitmap = 0;
1196 for (j = 0; j < NUM_LANG_FILES; j++)
1198 if (!strcmp(input_file, lang_files[j]))
1200 for (k = 0; k < NUM_BASE_FILES; k++)
1202 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1203 bitmap |= (1 << k);
1208 /* Otherwise, set all languages. */
1209 if (!bitmap)
1210 bitmap = (1 << NUM_BASE_FILES) - 1;
1212 return bitmap;
1215 /* An output file, suitable for definitions, that can see declarations
1216 made in INPUT_FILE and is linked into every language that uses
1217 INPUT_FILE. */
1219 outf_p
1220 get_output_file_with_visibility (const char *input_file)
1222 outf_p r;
1223 size_t len;
1224 const char *basename;
1225 const char *for_name;
1226 const char *output_name;
1228 /* This can happen when we need a file with visibility on a
1229 structure that we've never seen. We have to just hope that it's
1230 globally visible. */
1231 if (input_file == NULL)
1232 input_file = "system.h";
1234 /* Determine the output file name. */
1235 basename = get_file_basename (input_file);
1237 len = strlen (basename);
1238 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1239 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1240 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1242 char *s;
1244 output_name = s = xasprintf ("gt-%s", basename);
1245 for (; *s != '.'; s++)
1246 if (! ISALNUM (*s) && *s != '-')
1247 *s = '-';
1248 memcpy (s, ".h", sizeof (".h"));
1249 for_name = basename;
1251 /* Some headers get used by more than one front-end; hence, it
1252 would be inappropriate to spew them out to a single gtype-<lang>.h
1253 (and gengtype doesn't know how to direct spewage into multiple
1254 gtype-<lang>.h headers at this time). Instead, we pair up these
1255 headers with source files (and their special purpose gt-*.h headers). */
1256 else if (strcmp (basename, "c-common.h") == 0)
1257 output_name = "gt-c-common.h", for_name = "c-common.c";
1258 else if (strcmp (basename, "c-tree.h") == 0)
1259 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1260 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1261 && strcmp (basename + 3, "cp-tree.h") == 0)
1262 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1263 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1264 && strcmp (basename + 3, "decl.h") == 0)
1265 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1266 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1267 && strcmp (basename + 3, "name-lookup.h") == 0)
1268 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1269 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1270 && strcmp (basename + 5, "objc-act.h") == 0)
1271 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1272 else
1274 size_t i;
1276 for (i = 0; i < NUM_BASE_FILES; i++)
1277 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1278 && basename[strlen(lang_dir_names[i])] == '/')
1279 return base_files[i];
1281 output_name = "gtype-desc.c";
1282 for_name = NULL;
1285 /* Look through to see if we've ever seen this output filename before. */
1286 for (r = output_files; r; r = r->next)
1287 if (strcmp (r->name, output_name) == 0)
1288 return r;
1290 /* If not, create it. */
1291 r = create_file (for_name, output_name);
1293 return r;
1296 /* The name of an output file, suitable for definitions, that can see
1297 declarations made in INPUT_FILE and is linked into every language
1298 that uses INPUT_FILE. */
1300 const char *
1301 get_output_file_name (const char *input_file)
1303 return get_output_file_with_visibility (input_file)->name;
1306 /* Copy the output to its final destination,
1307 but don't unnecessarily change modification times. */
1309 static void
1310 close_output_files (void)
1312 outf_p of;
1314 for (of = output_files; of; of = of->next)
1316 FILE * newfile;
1318 newfile = fopen (of->name, "r");
1319 if (newfile != NULL )
1321 int no_write_p;
1322 size_t i;
1324 for (i = 0; i < of->bufused; i++)
1326 int ch;
1327 ch = fgetc (newfile);
1328 if (ch == EOF || ch != (unsigned char) of->buf[i])
1329 break;
1331 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1332 fclose (newfile);
1334 if (no_write_p)
1335 continue;
1338 newfile = fopen (of->name, "w");
1339 if (newfile == NULL)
1341 perror ("opening output file");
1342 exit (1);
1344 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1346 perror ("writing output file");
1347 exit (1);
1349 if (fclose (newfile) != 0)
1351 perror ("closing output file");
1352 exit (1);
1357 struct flist {
1358 struct flist *next;
1359 int started_p;
1360 const char *name;
1361 outf_p f;
1364 struct walk_type_data;
1366 /* For scalars and strings, given the item in 'val'.
1367 For structures, given a pointer to the item in 'val'.
1368 For misc. pointers, given the item in 'val'.
1370 typedef void (*process_field_fn)
1371 (type_p f, const struct walk_type_data *p);
1372 typedef void (*func_name_fn)
1373 (type_p s, const struct walk_type_data *p);
1375 /* Parameters for write_types. */
1377 struct write_types_data
1379 const char *prefix;
1380 const char *param_prefix;
1381 const char *subfield_marker_routine;
1382 const char *marker_routine;
1383 const char *reorder_note_routine;
1384 const char *comment;
1385 int skip_hooks; /* skip hook generation if non zero */
1388 static void output_escaped_param (struct walk_type_data *d,
1389 const char *, const char *);
1390 static void output_mangled_typename (outf_p, type_p);
1391 static void walk_type (type_p t, struct walk_type_data *d);
1392 static void write_func_for_structure
1393 (type_p orig_s, type_p s, type_p * param,
1394 const struct write_types_data *wtd);
1395 static void write_types_process_field
1396 (type_p f, const struct walk_type_data *d);
1397 static void write_types (type_p structures,
1398 type_p param_structs,
1399 const struct write_types_data *wtd);
1400 static void write_types_local_process_field
1401 (type_p f, const struct walk_type_data *d);
1402 static void write_local_func_for_structure
1403 (type_p orig_s, type_p s, type_p * param);
1404 static void write_local (type_p structures,
1405 type_p param_structs);
1406 static void write_enum_defn (type_p structures, type_p param_structs);
1407 static int contains_scalar_p (type_p t);
1408 static void put_mangled_filename (outf_p , const char *);
1409 static void finish_root_table (struct flist *flp, const char *pfx,
1410 const char *tname, const char *lastname,
1411 const char *name);
1412 static void write_root (outf_p , pair_p, type_p, const char *, int,
1413 struct fileloc *, const char *);
1414 static void write_array (outf_p f, pair_p v,
1415 const struct write_types_data *wtd);
1416 static void write_roots (pair_p);
1418 /* Parameters for walk_type. */
1420 struct walk_type_data
1422 process_field_fn process_field;
1423 const void *cookie;
1424 outf_p of;
1425 options_p opt;
1426 const char *val;
1427 const char *prev_val[4];
1428 int indent;
1429 int counter;
1430 struct fileloc *line;
1431 lang_bitmap bitmap;
1432 type_p *param;
1433 int used_length;
1434 type_p orig_s;
1435 const char *reorder_fn;
1436 bool needs_cast_p;
1437 bool fn_wants_lvalue;
1440 /* Print a mangled name representing T to OF. */
1442 static void
1443 output_mangled_typename (outf_p of, type_p t)
1445 if (t == NULL)
1446 oprintf (of, "Z");
1447 else switch (t->kind)
1449 case TYPE_POINTER:
1450 oprintf (of, "P");
1451 output_mangled_typename (of, t->u.p);
1452 break;
1453 case TYPE_SCALAR:
1454 oprintf (of, "I");
1455 break;
1456 case TYPE_STRING:
1457 oprintf (of, "S");
1458 break;
1459 case TYPE_STRUCT:
1460 case TYPE_UNION:
1461 case TYPE_LANG_STRUCT:
1462 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1463 break;
1464 case TYPE_PARAM_STRUCT:
1466 int i;
1467 for (i = 0; i < NUM_PARAM; i++)
1468 if (t->u.param_struct.param[i] != NULL)
1469 output_mangled_typename (of, t->u.param_struct.param[i]);
1470 output_mangled_typename (of, t->u.param_struct.stru);
1472 break;
1473 case TYPE_ARRAY:
1474 gcc_unreachable ();
1478 /* Print PARAM to D->OF processing escapes. D->VAL references the
1479 current object, D->PREV_VAL the object containing the current
1480 object, ONAME is the name of the option and D->LINE is used to
1481 print error messages. */
1483 static void
1484 output_escaped_param (struct walk_type_data *d, const char *param,
1485 const char *oname)
1487 const char *p;
1489 for (p = param; *p; p++)
1490 if (*p != '%')
1491 oprintf (d->of, "%c", *p);
1492 else switch (*++p)
1494 case 'h':
1495 oprintf (d->of, "(%s)", d->prev_val[2]);
1496 break;
1497 case '0':
1498 oprintf (d->of, "(%s)", d->prev_val[0]);
1499 break;
1500 case '1':
1501 oprintf (d->of, "(%s)", d->prev_val[1]);
1502 break;
1503 case 'a':
1505 const char *pp = d->val + strlen (d->val);
1506 while (pp[-1] == ']')
1507 while (*pp != '[')
1508 pp--;
1509 oprintf (d->of, "%s", pp);
1511 break;
1512 default:
1513 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1514 oname, '%', *p);
1518 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1519 which is of type T. Write code to D->OF to constrain execution (at
1520 the point that D->PROCESS_FIELD is called) to the appropriate
1521 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1522 pointers to those objects. D->PREV_VAL lists the objects
1523 containing the current object, D->OPT is a list of options to
1524 apply, D->INDENT is the current indentation level, D->LINE is used
1525 to print error messages, D->BITMAP indicates which languages to
1526 print the structure for, and D->PARAM is the current parameter
1527 (from an enclosing param_is option). */
1529 static void
1530 walk_type (type_p t, 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 options_p oo;
1538 const struct nested_ptr_data *nested_ptr_d = NULL;
1540 d->needs_cast_p = false;
1541 for (oo = d->opt; oo; oo = oo->next)
1542 if (strcmp (oo->name, "length") == 0)
1543 length = oo->info;
1544 else if (strcmp (oo->name, "maybe_undef") == 0)
1545 maybe_undef_p = 1;
1546 else if (strncmp (oo->name, "use_param", 9) == 0
1547 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1548 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1549 else if (strcmp (oo->name, "use_params") == 0)
1550 use_params_p = 1;
1551 else if (strcmp (oo->name, "desc") == 0)
1552 desc = oo->info;
1553 else if (strcmp (oo->name, "mark_hook") == 0)
1555 else if (strcmp (oo->name, "nested_ptr") == 0)
1556 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1557 else if (strcmp (oo->name, "dot") == 0)
1559 else if (strcmp (oo->name, "tag") == 0)
1561 else if (strcmp (oo->name, "special") == 0)
1563 else if (strcmp (oo->name, "skip") == 0)
1565 else if (strcmp (oo->name, "default") == 0)
1567 else if (strcmp (oo->name, "descbits") == 0)
1569 else if (strcmp (oo->name, "param_is") == 0)
1571 else if (strncmp (oo->name, "param", 5) == 0
1572 && ISDIGIT (oo->name[5])
1573 && strcmp (oo->name + 6, "_is") == 0)
1575 else if (strcmp (oo->name, "chain_next") == 0)
1577 else if (strcmp (oo->name, "chain_prev") == 0)
1579 else if (strcmp (oo->name, "reorder") == 0)
1581 else
1582 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1584 if (d->used_length)
1585 length = NULL;
1587 if (use_params_p)
1589 int pointer_p = t->kind == TYPE_POINTER;
1591 if (pointer_p)
1592 t = t->u.p;
1593 if (! UNION_OR_STRUCT_P (t))
1594 error_at_line (d->line, "`use_params' option on unimplemented type");
1595 else
1596 t = find_param_structure (t, d->param);
1597 if (pointer_p)
1598 t = create_pointer (t);
1601 if (use_param_num != -1)
1603 if (d->param != NULL && d->param[use_param_num] != NULL)
1605 type_p nt = d->param[use_param_num];
1607 if (t->kind == TYPE_ARRAY)
1608 nt = create_array (nt, t->u.a.len);
1609 else if (length != NULL && t->kind == TYPE_POINTER)
1610 nt = create_pointer (nt);
1611 d->needs_cast_p = (t->kind != TYPE_POINTER
1612 && (nt->kind == TYPE_POINTER
1613 || nt->kind == TYPE_STRING));
1614 t = nt;
1616 else
1617 error_at_line (d->line, "no parameter defined for `%s'",
1618 d->val);
1621 if (maybe_undef_p
1622 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1624 error_at_line (d->line,
1625 "field `%s' has invalid option `maybe_undef_p'\n",
1626 d->val);
1627 return;
1630 switch (t->kind)
1632 case TYPE_SCALAR:
1633 case TYPE_STRING:
1634 d->process_field (t, d);
1635 break;
1637 case TYPE_POINTER:
1639 if (maybe_undef_p
1640 && t->u.p->u.s.line.file == NULL)
1642 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1643 break;
1646 if (! length)
1648 if (! UNION_OR_STRUCT_P (t->u.p)
1649 && t->u.p->kind != TYPE_PARAM_STRUCT)
1651 error_at_line (d->line,
1652 "field `%s' is pointer to unimplemented type",
1653 d->val);
1654 break;
1657 if (nested_ptr_d)
1659 const char *oldprevval2 = d->prev_val[2];
1661 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1663 error_at_line (d->line,
1664 "field `%s' has invalid "
1665 "option `nested_ptr'\n",
1666 d->val);
1667 return;
1670 d->prev_val[2] = d->val;
1671 oprintf (d->of, "%*s{\n", d->indent, "");
1672 d->indent += 2;
1673 d->val = xasprintf ("x%d", d->counter++);
1674 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1675 (nested_ptr_d->type->kind == TYPE_UNION
1676 ? "union" : "struct"),
1677 nested_ptr_d->type->u.s.tag,
1678 d->fn_wants_lvalue ? "" : "const ",
1679 d->val);
1680 oprintf (d->of, "%*s", d->indent + 2, "");
1681 output_escaped_param (d, nested_ptr_d->convert_from,
1682 "nested_ptr");
1683 oprintf (d->of, ";\n");
1685 d->process_field (nested_ptr_d->type, d);
1687 if (d->fn_wants_lvalue)
1689 oprintf (d->of, "%*s%s = ", d->indent, "",
1690 d->prev_val[2]);
1691 d->prev_val[2] = d->val;
1692 output_escaped_param (d, nested_ptr_d->convert_to,
1693 "nested_ptr");
1694 oprintf (d->of, ";\n");
1697 d->indent -= 2;
1698 oprintf (d->of, "%*s}\n", d->indent, "");
1699 d->val = d->prev_val[2];
1700 d->prev_val[2] = oldprevval2;
1702 else
1703 d->process_field (t->u.p, d);
1705 else
1707 int loopcounter = d->counter++;
1708 const char *oldval = d->val;
1709 const char *oldprevval3 = d->prev_val[3];
1710 char *newval;
1712 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1713 d->indent += 2;
1714 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1715 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1716 loopcounter, loopcounter);
1717 output_escaped_param (d, length, "length");
1718 oprintf (d->of, "); i%d++) {\n", loopcounter);
1719 d->indent += 2;
1720 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1721 d->used_length = 1;
1722 d->prev_val[3] = oldval;
1723 walk_type (t->u.p, d);
1724 free (newval);
1725 d->val = oldval;
1726 d->prev_val[3] = oldprevval3;
1727 d->used_length = 0;
1728 d->indent -= 2;
1729 oprintf (d->of, "%*s}\n", d->indent, "");
1730 d->process_field(t, d);
1731 d->indent -= 2;
1732 oprintf (d->of, "%*s}\n", d->indent, "");
1735 break;
1737 case TYPE_ARRAY:
1739 int loopcounter = d->counter++;
1740 const char *oldval = d->val;
1741 char *newval;
1743 /* If it's an array of scalars, we optimize by not generating
1744 any code. */
1745 if (t->u.a.p->kind == TYPE_SCALAR)
1746 break;
1748 oprintf (d->of, "%*s{\n", d->indent, "");
1749 d->indent += 2;
1750 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1751 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1752 loopcounter, loopcounter);
1753 if (length)
1754 output_escaped_param (d, length, "length");
1755 else
1756 oprintf (d->of, "%s", t->u.a.len);
1757 oprintf (d->of, "); i%d++) {\n", loopcounter);
1758 d->indent += 2;
1759 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1760 d->used_length = 1;
1761 walk_type (t->u.a.p, d);
1762 free (newval);
1763 d->used_length = 0;
1764 d->val = oldval;
1765 d->indent -= 2;
1766 oprintf (d->of, "%*s}\n", d->indent, "");
1767 d->indent -= 2;
1768 oprintf (d->of, "%*s}\n", d->indent, "");
1770 break;
1772 case TYPE_STRUCT:
1773 case TYPE_UNION:
1775 pair_p f;
1776 const char *oldval = d->val;
1777 const char *oldprevval1 = d->prev_val[1];
1778 const char *oldprevval2 = d->prev_val[2];
1779 const int union_p = t->kind == TYPE_UNION;
1780 int seen_default_p = 0;
1781 options_p o;
1783 if (! t->u.s.line.file)
1784 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1786 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1788 error_at_line (d->line,
1789 "structure `%s' defined for mismatching languages",
1790 t->u.s.tag);
1791 error_at_line (&t->u.s.line, "one structure defined here");
1794 /* Some things may also be defined in the structure's options. */
1795 for (o = t->u.s.opt; o; o = o->next)
1796 if (! desc && strcmp (o->name, "desc") == 0)
1797 desc = o->info;
1799 d->prev_val[2] = oldval;
1800 d->prev_val[1] = oldprevval2;
1801 if (union_p)
1803 if (desc == NULL)
1805 error_at_line (d->line, "missing `desc' option for union `%s'",
1806 t->u.s.tag);
1807 desc = "1";
1809 oprintf (d->of, "%*sswitch (", d->indent, "");
1810 output_escaped_param (d, desc, "desc");
1811 oprintf (d->of, ")\n");
1812 d->indent += 2;
1813 oprintf (d->of, "%*s{\n", d->indent, "");
1815 for (f = t->u.s.fields; f; f = f->next)
1817 options_p oo;
1818 const char *dot = ".";
1819 const char *tagid = NULL;
1820 int skip_p = 0;
1821 int default_p = 0;
1822 int use_param_p = 0;
1823 char *newval;
1825 d->reorder_fn = NULL;
1826 for (oo = f->opt; oo; oo = oo->next)
1827 if (strcmp (oo->name, "dot") == 0)
1828 dot = oo->info;
1829 else if (strcmp (oo->name, "tag") == 0)
1830 tagid = oo->info;
1831 else if (strcmp (oo->name, "skip") == 0)
1832 skip_p = 1;
1833 else if (strcmp (oo->name, "default") == 0)
1834 default_p = 1;
1835 else if (strcmp (oo->name, "reorder") == 0)
1836 d->reorder_fn = oo->info;
1837 else if (strncmp (oo->name, "use_param", 9) == 0
1838 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1839 use_param_p = 1;
1841 if (skip_p)
1842 continue;
1844 if (union_p && tagid)
1846 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1847 d->indent += 2;
1849 else if (union_p && default_p)
1851 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1852 d->indent += 2;
1853 seen_default_p = 1;
1855 else if (! union_p && (default_p || tagid))
1856 error_at_line (d->line,
1857 "can't use `%s' outside a union on field `%s'",
1858 default_p ? "default" : "tag", f->name);
1859 else if (union_p && ! (default_p || tagid)
1860 && f->type->kind == TYPE_SCALAR)
1862 fprintf (stderr,
1863 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1864 d->line->file, d->line->line, f->name);
1865 continue;
1867 else if (union_p && ! (default_p || tagid))
1868 error_at_line (d->line,
1869 "field `%s' is missing `tag' or `default' option",
1870 f->name);
1872 d->line = &f->line;
1873 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1874 d->opt = f->opt;
1875 d->used_length = false;
1877 if (union_p && use_param_p && d->param == NULL)
1878 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1879 else
1880 walk_type (f->type, d);
1882 free (newval);
1884 if (union_p)
1886 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1887 d->indent -= 2;
1890 d->reorder_fn = NULL;
1892 d->val = oldval;
1893 d->prev_val[1] = oldprevval1;
1894 d->prev_val[2] = oldprevval2;
1896 if (union_p && ! seen_default_p)
1898 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1899 oprintf (d->of, "%*s break;\n", d->indent, "");
1901 if (union_p)
1903 oprintf (d->of, "%*s}\n", d->indent, "");
1904 d->indent -= 2;
1907 break;
1909 case TYPE_LANG_STRUCT:
1911 type_p nt;
1912 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1913 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1914 break;
1915 if (nt == NULL)
1916 error_at_line (d->line, "structure `%s' differs between languages",
1917 t->u.s.tag);
1918 else
1919 walk_type (nt, d);
1921 break;
1923 case TYPE_PARAM_STRUCT:
1925 type_p *oldparam = d->param;
1927 d->param = t->u.param_struct.param;
1928 walk_type (t->u.param_struct.stru, d);
1929 d->param = oldparam;
1931 break;
1933 default:
1934 gcc_unreachable ();
1938 /* process_field routine for marking routines. */
1940 static void
1941 write_types_process_field (type_p f, const struct walk_type_data *d)
1943 const struct write_types_data *wtd;
1944 const char *cast = d->needs_cast_p ? "(void *)" : "";
1945 wtd = (const struct write_types_data *) d->cookie;
1947 switch (f->kind)
1949 case TYPE_POINTER:
1950 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1951 wtd->subfield_marker_routine, cast, d->val);
1952 if (wtd->param_prefix)
1954 oprintf (d->of, ", %s", d->prev_val[3]);
1955 if (d->orig_s)
1957 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1958 output_mangled_typename (d->of, d->orig_s);
1960 else
1961 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1963 if (f->u.p->kind == TYPE_PARAM_STRUCT
1964 && f->u.p->u.s.line.file != NULL)
1966 oprintf (d->of, ", gt_e_");
1967 output_mangled_typename (d->of, f);
1969 else if (UNION_OR_STRUCT_P (f)
1970 && f->u.p->u.s.line.file != NULL)
1972 oprintf (d->of, ", gt_ggc_e_");
1973 output_mangled_typename (d->of, f);
1975 else
1976 oprintf (d->of, ", gt_types_enum_last");
1978 oprintf (d->of, ");\n");
1979 if (d->reorder_fn && wtd->reorder_note_routine)
1980 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1981 wtd->reorder_note_routine, cast, d->val,
1982 d->prev_val[3], d->reorder_fn);
1983 break;
1985 case TYPE_STRING:
1986 if (wtd->param_prefix == NULL)
1987 break;
1989 case TYPE_STRUCT:
1990 case TYPE_UNION:
1991 case TYPE_LANG_STRUCT:
1992 case TYPE_PARAM_STRUCT:
1993 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1994 output_mangled_typename (d->of, f);
1995 oprintf (d->of, " (%s%s);\n", cast, d->val);
1996 if (d->reorder_fn && wtd->reorder_note_routine)
1997 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1998 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1999 d->reorder_fn);
2000 break;
2002 case TYPE_SCALAR:
2003 break;
2005 default:
2006 gcc_unreachable ();
2010 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
2012 static void
2013 output_type_enum (outf_p of, type_p s)
2015 if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2017 oprintf (of, ", gt_e_");
2018 output_mangled_typename (of, s);
2020 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2022 oprintf (of, ", gt_ggc_e_");
2023 output_mangled_typename (of, s);
2025 else
2026 oprintf (of, ", gt_types_enum_last");
2029 /* For S, a structure that's part of ORIG_S, and using parameters
2030 PARAM, write out a routine that:
2031 - Takes a parameter, a void * but actually of type *S
2032 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2033 field of S or its substructures and (in some cases) things
2034 that are pointed to by S.
2037 static void
2038 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2039 const struct write_types_data *wtd)
2041 const char *fn = s->u.s.line.file;
2042 int i;
2043 const char *chain_next = NULL;
2044 const char *chain_prev = NULL;
2045 const char *mark_hook_name = NULL;
2046 options_p opt;
2047 struct walk_type_data d;
2049 /* This is a hack, and not the good kind either. */
2050 for (i = NUM_PARAM - 1; i >= 0; i--)
2051 if (param && param[i] && param[i]->kind == TYPE_POINTER
2052 && UNION_OR_STRUCT_P (param[i]->u.p))
2053 fn = param[i]->u.p->u.s.line.file;
2055 memset (&d, 0, sizeof (d));
2056 d.of = get_output_file_with_visibility (fn);
2058 for (opt = s->u.s.opt; opt; opt = opt->next)
2059 if (strcmp (opt->name, "chain_next") == 0)
2060 chain_next = opt->info;
2061 else if (strcmp (opt->name, "chain_prev") == 0)
2062 chain_prev = opt->info;
2063 else if (strcmp (opt->name, "mark_hook") == 0)
2064 mark_hook_name = opt->info;
2066 if (chain_prev != NULL && chain_next == NULL)
2067 error_at_line (&s->u.s.line, "chain_prev without chain_next");
2069 d.process_field = write_types_process_field;
2070 d.cookie = wtd;
2071 d.orig_s = orig_s;
2072 d.opt = s->u.s.opt;
2073 d.line = &s->u.s.line;
2074 d.bitmap = s->u.s.bitmap;
2075 d.param = param;
2076 d.prev_val[0] = "*x";
2077 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2078 d.prev_val[3] = "x";
2079 d.val = "(*x)";
2081 oprintf (d.of, "\n");
2082 oprintf (d.of, "void\n");
2083 if (param == NULL)
2084 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2085 else
2087 oprintf (d.of, "gt_%s_", wtd->prefix);
2088 output_mangled_typename (d.of, orig_s);
2090 oprintf (d.of, " (void *x_p)\n");
2091 oprintf (d.of, "{\n");
2092 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2093 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2094 chain_next == NULL ? "const " : "",
2095 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2096 if (chain_next != NULL)
2097 oprintf (d.of, " %s %s * xlimit = x;\n",
2098 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2099 if (chain_next == NULL)
2101 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2102 if (wtd->param_prefix)
2104 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2105 output_mangled_typename (d.of, orig_s);
2106 output_type_enum (d.of, orig_s);
2108 oprintf (d.of, "))\n");
2110 else
2112 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2113 if (wtd->param_prefix)
2115 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2116 output_mangled_typename (d.of, orig_s);
2117 output_type_enum (d.of, orig_s);
2119 oprintf (d.of, "))\n");
2120 if (mark_hook_name && !wtd->skip_hooks)
2122 oprintf (d.of, " {\n");
2123 oprintf (d.of, " %s (xlimit);\n ", mark_hook_name);
2125 oprintf (d.of, " xlimit = (");
2126 d.prev_val[2] = "*xlimit";
2127 output_escaped_param (&d, chain_next, "chain_next");
2128 oprintf (d.of, ");\n");
2129 if (mark_hook_name && !wtd->skip_hooks)
2130 oprintf (d.of, " }\n");
2131 if (chain_prev != NULL)
2133 oprintf (d.of, " if (x != xlimit)\n");
2134 oprintf (d.of, " for (;;)\n");
2135 oprintf (d.of, " {\n");
2136 oprintf (d.of, " %s %s * const xprev = (",
2137 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2139 d.prev_val[2] = "*x";
2140 output_escaped_param (&d, chain_prev, "chain_prev");
2141 oprintf (d.of, ");\n");
2142 oprintf (d.of, " if (xprev == NULL) break;\n");
2143 oprintf (d.of, " x = xprev;\n");
2144 oprintf (d.of, " (void) %s (xprev",
2145 wtd->marker_routine);
2146 if (wtd->param_prefix)
2148 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2149 output_mangled_typename (d.of, orig_s);
2150 output_type_enum (d.of, orig_s);
2152 oprintf (d.of, ");\n");
2153 oprintf (d.of, " }\n");
2155 oprintf (d.of, " while (x != xlimit)\n");
2157 oprintf (d.of, " {\n");
2158 if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2160 oprintf (d.of, " %s (x);\n", mark_hook_name);
2162 d.prev_val[2] = "*x";
2163 d.indent = 6;
2164 walk_type (s, &d);
2166 if (chain_next != NULL)
2168 oprintf (d.of, " x = (");
2169 output_escaped_param (&d, chain_next, "chain_next");
2170 oprintf (d.of, ");\n");
2173 oprintf (d.of, " }\n");
2174 oprintf (d.of, "}\n");
2177 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2179 static void
2180 write_types (type_p structures, type_p param_structs,
2181 const struct write_types_data *wtd)
2183 type_p s;
2185 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2186 for (s = structures; s; s = s->next)
2187 if (s->gc_used == GC_POINTED_TO
2188 || s->gc_used == GC_MAYBE_POINTED_TO)
2190 options_p opt;
2192 if (s->gc_used == GC_MAYBE_POINTED_TO
2193 && s->u.s.line.file == NULL)
2194 continue;
2196 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2197 output_mangled_typename (header_file, s);
2198 oprintf (header_file, "(X) do { \\\n");
2199 oprintf (header_file,
2200 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2201 s->u.s.tag);
2202 oprintf (header_file,
2203 " } while (0)\n");
2205 for (opt = s->u.s.opt; opt; opt = opt->next)
2206 if (strcmp (opt->name, "ptr_alias") == 0)
2208 type_p t = (type_p) opt->info;
2209 if (t->kind == TYPE_STRUCT
2210 || t->kind == TYPE_UNION
2211 || t->kind == TYPE_LANG_STRUCT)
2212 oprintf (header_file,
2213 "#define gt_%sx_%s gt_%sx_%s\n",
2214 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2215 else
2216 error_at_line (&s->u.s.line,
2217 "structure alias is not a structure");
2218 break;
2220 if (opt)
2221 continue;
2223 /* Declare the marker procedure only once. */
2224 oprintf (header_file,
2225 "extern void gt_%sx_%s (void *);\n",
2226 wtd->prefix, s->u.s.tag);
2228 if (s->u.s.line.file == NULL)
2230 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2231 s->u.s.tag);
2232 continue;
2235 if (s->kind == TYPE_LANG_STRUCT)
2237 type_p ss;
2238 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2239 write_func_for_structure (s, ss, NULL, wtd);
2241 else
2242 write_func_for_structure (s, s, NULL, wtd);
2245 for (s = param_structs; s; s = s->next)
2246 if (s->gc_used == GC_POINTED_TO)
2248 type_p * param = s->u.param_struct.param;
2249 type_p stru = s->u.param_struct.stru;
2251 /* Declare the marker procedure. */
2252 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2253 output_mangled_typename (header_file, s);
2254 oprintf (header_file, " (void *);\n");
2256 if (stru->u.s.line.file == NULL)
2258 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2259 s->u.s.tag);
2260 continue;
2263 if (stru->kind == TYPE_LANG_STRUCT)
2265 type_p ss;
2266 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2267 write_func_for_structure (s, ss, param, wtd);
2269 else
2270 write_func_for_structure (s, stru, param, wtd);
2274 static const struct write_types_data ggc_wtd =
2276 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2277 "GC marker procedures. ",
2278 FALSE
2281 static const struct write_types_data pch_wtd =
2283 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2284 "gt_pch_note_reorder",
2285 "PCH type-walking procedures. ",
2286 TRUE
2289 /* Write out the local pointer-walking routines. */
2291 /* process_field routine for local pointer-walking. */
2293 static void
2294 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2296 switch (f->kind)
2298 case TYPE_POINTER:
2299 case TYPE_STRUCT:
2300 case TYPE_UNION:
2301 case TYPE_LANG_STRUCT:
2302 case TYPE_PARAM_STRUCT:
2303 case TYPE_STRING:
2304 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2305 d->prev_val[3]);
2306 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2307 break;
2309 case TYPE_SCALAR:
2310 break;
2312 default:
2313 gcc_unreachable ();
2317 /* For S, a structure that's part of ORIG_S, and using parameters
2318 PARAM, write out a routine that:
2319 - Is of type gt_note_pointers
2320 - Calls PROCESS_FIELD on each field of S or its substructures.
2323 static void
2324 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2326 const char *fn = s->u.s.line.file;
2327 int i;
2328 struct walk_type_data d;
2330 /* This is a hack, and not the good kind either. */
2331 for (i = NUM_PARAM - 1; i >= 0; i--)
2332 if (param && param[i] && param[i]->kind == TYPE_POINTER
2333 && UNION_OR_STRUCT_P (param[i]->u.p))
2334 fn = param[i]->u.p->u.s.line.file;
2336 memset (&d, 0, sizeof (d));
2337 d.of = get_output_file_with_visibility (fn);
2339 d.process_field = write_types_local_process_field;
2340 d.opt = s->u.s.opt;
2341 d.line = &s->u.s.line;
2342 d.bitmap = s->u.s.bitmap;
2343 d.param = param;
2344 d.prev_val[0] = d.prev_val[2] = "*x";
2345 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2346 d.prev_val[3] = "x";
2347 d.val = "(*x)";
2348 d.fn_wants_lvalue = true;
2350 oprintf (d.of, "\n");
2351 oprintf (d.of, "void\n");
2352 oprintf (d.of, "gt_pch_p_");
2353 output_mangled_typename (d.of, orig_s);
2354 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2355 "\tvoid *x_p,\n"
2356 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2357 "\tATTRIBUTE_UNUSED void *cookie)\n");
2358 oprintf (d.of, "{\n");
2359 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2360 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2361 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2362 d.indent = 2;
2363 walk_type (s, &d);
2364 oprintf (d.of, "}\n");
2367 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2369 static void
2370 write_local (type_p structures, type_p param_structs)
2372 type_p s;
2374 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2375 for (s = structures; s; s = s->next)
2376 if (s->gc_used == GC_POINTED_TO
2377 || s->gc_used == GC_MAYBE_POINTED_TO)
2379 options_p opt;
2381 if (s->u.s.line.file == NULL)
2382 continue;
2384 for (opt = s->u.s.opt; opt; opt = opt->next)
2385 if (strcmp (opt->name, "ptr_alias") == 0)
2387 type_p t = (type_p) opt->info;
2388 if (t->kind == TYPE_STRUCT
2389 || t->kind == TYPE_UNION
2390 || t->kind == TYPE_LANG_STRUCT)
2392 oprintf (header_file, "#define gt_pch_p_");
2393 output_mangled_typename (header_file, s);
2394 oprintf (header_file, " gt_pch_p_");
2395 output_mangled_typename (header_file, t);
2396 oprintf (header_file, "\n");
2398 else
2399 error_at_line (&s->u.s.line,
2400 "structure alias is not a structure");
2401 break;
2403 if (opt)
2404 continue;
2406 /* Declare the marker procedure only once. */
2407 oprintf (header_file, "extern void gt_pch_p_");
2408 output_mangled_typename (header_file, s);
2409 oprintf (header_file,
2410 "\n (void *, void *, gt_pointer_operator, void *);\n");
2412 if (s->kind == TYPE_LANG_STRUCT)
2414 type_p ss;
2415 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2416 write_local_func_for_structure (s, ss, NULL);
2418 else
2419 write_local_func_for_structure (s, s, NULL);
2422 for (s = param_structs; s; s = s->next)
2423 if (s->gc_used == GC_POINTED_TO)
2425 type_p * param = s->u.param_struct.param;
2426 type_p stru = s->u.param_struct.stru;
2428 /* Declare the marker procedure. */
2429 oprintf (header_file, "extern void gt_pch_p_");
2430 output_mangled_typename (header_file, s);
2431 oprintf (header_file,
2432 "\n (void *, void *, gt_pointer_operator, void *);\n");
2434 if (stru->u.s.line.file == NULL)
2436 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2437 s->u.s.tag);
2438 continue;
2441 if (stru->kind == TYPE_LANG_STRUCT)
2443 type_p ss;
2444 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2445 write_local_func_for_structure (s, ss, param);
2447 else
2448 write_local_func_for_structure (s, stru, param);
2452 /* Write out the 'enum' definition for gt_types_enum. */
2454 static void
2455 write_enum_defn (type_p structures, type_p param_structs)
2457 type_p s;
2459 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2460 oprintf (header_file, "enum gt_types_enum {\n");
2461 for (s = structures; s; s = s->next)
2462 if (s->gc_used == GC_POINTED_TO
2463 || s->gc_used == GC_MAYBE_POINTED_TO)
2465 if (s->gc_used == GC_MAYBE_POINTED_TO
2466 && s->u.s.line.file == NULL)
2467 continue;
2469 oprintf (header_file, " gt_ggc_e_");
2470 output_mangled_typename (header_file, s);
2471 oprintf (header_file, ", \n");
2473 for (s = param_structs; s; s = s->next)
2474 if (s->gc_used == GC_POINTED_TO)
2476 oprintf (header_file, " gt_e_");
2477 output_mangled_typename (header_file, s);
2478 oprintf (header_file, ", \n");
2480 oprintf (header_file, " gt_types_enum_last\n");
2481 oprintf (header_file, "};\n");
2484 /* Might T contain any non-pointer elements? */
2486 static int
2487 contains_scalar_p (type_p t)
2489 switch (t->kind)
2491 case TYPE_STRING:
2492 case TYPE_POINTER:
2493 return 0;
2494 case TYPE_ARRAY:
2495 return contains_scalar_p (t->u.a.p);
2496 default:
2497 /* Could also check for structures that have no non-pointer
2498 fields, but there aren't enough of those to worry about. */
2499 return 1;
2503 /* Mangle FN and print it to F. */
2505 static void
2506 put_mangled_filename (outf_p f, const char *fn)
2508 const char *name = get_output_file_name (fn);
2509 for (; *name != 0; name++)
2510 if (ISALNUM (*name))
2511 oprintf (f, "%c", *name);
2512 else
2513 oprintf (f, "%c", '_');
2516 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2517 LASTNAME, and NAME are all strings to insert in various places in
2518 the resulting code. */
2520 static void
2521 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2522 const char *tname, const char *name)
2524 struct flist *fli2;
2526 for (fli2 = flp; fli2; fli2 = fli2->next)
2527 if (fli2->started_p)
2529 oprintf (fli2->f, " %s\n", lastname);
2530 oprintf (fli2->f, "};\n\n");
2533 for (fli2 = flp; fli2; fli2 = fli2->next)
2534 if (fli2->started_p)
2536 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2537 int fnum;
2539 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2540 if (bitmap & 1)
2542 oprintf (base_files[fnum],
2543 "extern const struct %s gt_%s_",
2544 tname, pfx);
2545 put_mangled_filename (base_files[fnum], fli2->name);
2546 oprintf (base_files[fnum], "[];\n");
2551 size_t fnum;
2552 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2553 oprintf (base_files [fnum],
2554 "const struct %s * const %s[] = {\n",
2555 tname, name);
2559 for (fli2 = flp; fli2; fli2 = fli2->next)
2560 if (fli2->started_p)
2562 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2563 int fnum;
2565 fli2->started_p = 0;
2567 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2568 if (bitmap & 1)
2570 oprintf (base_files[fnum], " gt_%s_", pfx);
2571 put_mangled_filename (base_files[fnum], fli2->name);
2572 oprintf (base_files[fnum], ",\n");
2577 size_t fnum;
2578 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2580 oprintf (base_files[fnum], " NULL\n");
2581 oprintf (base_files[fnum], "};\n");
2586 /* Write out to F the table entry and any marker routines needed to
2587 mark NAME as TYPE. The original variable is V, at LINE.
2588 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2589 is nonzero iff we are building the root table for hash table caches. */
2591 static void
2592 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2593 struct fileloc *line, const char *if_marked)
2595 switch (type->kind)
2597 case TYPE_STRUCT:
2599 pair_p fld;
2600 for (fld = type->u.s.fields; fld; fld = fld->next)
2602 int skip_p = 0;
2603 const char *desc = NULL;
2604 options_p o;
2606 for (o = fld->opt; o; o = o->next)
2607 if (strcmp (o->name, "skip") == 0)
2608 skip_p = 1;
2609 else if (strcmp (o->name, "desc") == 0)
2610 desc = o->info;
2611 else
2612 error_at_line (line,
2613 "field `%s' of global `%s' has unknown option `%s'",
2614 fld->name, name, o->name);
2616 if (skip_p)
2617 continue;
2618 else if (desc && fld->type->kind == TYPE_UNION)
2620 pair_p validf = NULL;
2621 pair_p ufld;
2623 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2625 const char *tag = NULL;
2626 options_p oo;
2628 for (oo = ufld->opt; oo; oo = oo->next)
2629 if (strcmp (oo->name, "tag") == 0)
2630 tag = oo->info;
2631 if (tag == NULL || strcmp (tag, desc) != 0)
2632 continue;
2633 if (validf != NULL)
2634 error_at_line (line,
2635 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2636 name, fld->name, validf->name,
2637 name, fld->name, ufld->name,
2638 tag);
2639 validf = ufld;
2641 if (validf != NULL)
2643 char *newname;
2644 newname = xasprintf ("%s.%s.%s",
2645 name, fld->name, validf->name);
2646 write_root (f, v, validf->type, newname, 0, line,
2647 if_marked);
2648 free (newname);
2651 else if (desc)
2652 error_at_line (line,
2653 "global `%s.%s' has `desc' option but is not union",
2654 name, fld->name);
2655 else
2657 char *newname;
2658 newname = xasprintf ("%s.%s", name, fld->name);
2659 write_root (f, v, fld->type, newname, 0, line, if_marked);
2660 free (newname);
2664 break;
2666 case TYPE_ARRAY:
2668 char *newname;
2669 newname = xasprintf ("%s[0]", name);
2670 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2671 free (newname);
2673 break;
2675 case TYPE_POINTER:
2677 type_p ap, tp;
2679 oprintf (f, " {\n");
2680 oprintf (f, " &%s,\n", name);
2681 oprintf (f, " 1");
2683 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2684 if (ap->u.a.len[0])
2685 oprintf (f, " * (%s)", ap->u.a.len);
2686 else if (ap == v->type)
2687 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2688 oprintf (f, ",\n");
2689 oprintf (f, " sizeof (%s", v->name);
2690 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2691 oprintf (f, "[0]");
2692 oprintf (f, "),\n");
2694 tp = type->u.p;
2696 if (! has_length && UNION_OR_STRUCT_P (tp))
2698 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2699 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2701 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2703 oprintf (f, " &gt_ggc_m_");
2704 output_mangled_typename (f, tp);
2705 oprintf (f, ",\n &gt_pch_n_");
2706 output_mangled_typename (f, tp);
2708 else if (has_length
2709 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2711 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2712 oprintf (f, " &gt_pch_na_%s", name);
2714 else
2716 error_at_line (line,
2717 "global `%s' is pointer to unimplemented type",
2718 name);
2720 if (if_marked)
2721 oprintf (f, ",\n &%s", if_marked);
2722 oprintf (f, "\n },\n");
2724 break;
2726 case TYPE_STRING:
2728 oprintf (f, " {\n");
2729 oprintf (f, " &%s,\n", name);
2730 oprintf (f, " 1, \n");
2731 oprintf (f, " sizeof (%s),\n", v->name);
2732 oprintf (f, " &gt_ggc_m_S,\n");
2733 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2734 oprintf (f, " },\n");
2736 break;
2738 case TYPE_SCALAR:
2739 break;
2741 default:
2742 error_at_line (line,
2743 "global `%s' is unimplemented type",
2744 name);
2748 /* This generates a routine to walk an array. */
2750 static void
2751 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2753 struct walk_type_data d;
2754 char *prevval3;
2756 memset (&d, 0, sizeof (d));
2757 d.of = f;
2758 d.cookie = wtd;
2759 d.indent = 2;
2760 d.line = &v->line;
2761 d.opt = v->opt;
2762 d.bitmap = get_base_file_bitmap (v->line.file);
2763 d.param = NULL;
2765 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2767 if (wtd->param_prefix)
2769 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2770 oprintf (f,
2771 " (void *, void *, gt_pointer_operator, void *);\n");
2772 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2773 wtd->param_prefix, v->name);
2774 oprintf (d.of,
2775 " ATTRIBUTE_UNUSED void *x_p,\n"
2776 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2777 " ATTRIBUTE_UNUSED void * cookie)\n");
2778 oprintf (d.of, "{\n");
2779 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2780 d.process_field = write_types_local_process_field;
2781 walk_type (v->type, &d);
2782 oprintf (f, "}\n\n");
2785 d.opt = v->opt;
2786 oprintf (f, "static void gt_%sa_%s (void *);\n",
2787 wtd->prefix, v->name);
2788 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2789 wtd->prefix, v->name);
2790 oprintf (f, "{\n");
2791 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2792 d.process_field = write_types_process_field;
2793 walk_type (v->type, &d);
2794 free (prevval3);
2795 oprintf (f, "}\n\n");
2798 /* Output a table describing the locations and types of VARIABLES. */
2800 static void
2801 write_roots (pair_p variables)
2803 pair_p v;
2804 struct flist *flp = NULL;
2806 for (v = variables; v; v = v->next)
2808 outf_p f = get_output_file_with_visibility (v->line.file);
2809 struct flist *fli;
2810 const char *length = NULL;
2811 int deletable_p = 0;
2812 options_p o;
2814 for (o = v->opt; o; o = o->next)
2815 if (strcmp (o->name, "length") == 0)
2816 length = o->info;
2817 else if (strcmp (o->name, "deletable") == 0)
2818 deletable_p = 1;
2819 else if (strcmp (o->name, "param_is") == 0)
2821 else if (strncmp (o->name, "param", 5) == 0
2822 && ISDIGIT (o->name[5])
2823 && strcmp (o->name + 6, "_is") == 0)
2825 else if (strcmp (o->name, "if_marked") == 0)
2827 else
2828 error_at_line (&v->line,
2829 "global `%s' has unknown option `%s'",
2830 v->name, o->name);
2832 for (fli = flp; fli; fli = fli->next)
2833 if (fli->f == f)
2834 break;
2835 if (fli == NULL)
2837 fli = XNEW (struct flist);
2838 fli->f = f;
2839 fli->next = flp;
2840 fli->started_p = 0;
2841 fli->name = v->line.file;
2842 flp = fli;
2844 oprintf (f, "\n/* GC roots. */\n\n");
2847 if (! deletable_p
2848 && length
2849 && v->type->kind == TYPE_POINTER
2850 && (v->type->u.p->kind == TYPE_POINTER
2851 || v->type->u.p->kind == TYPE_STRUCT))
2853 write_array (f, v, &ggc_wtd);
2854 write_array (f, v, &pch_wtd);
2858 for (v = variables; v; v = v->next)
2860 outf_p f = get_output_file_with_visibility (v->line.file);
2861 struct flist *fli;
2862 int skip_p = 0;
2863 int length_p = 0;
2864 options_p o;
2866 for (o = v->opt; o; o = o->next)
2867 if (strcmp (o->name, "length") == 0)
2868 length_p = 1;
2869 else if (strcmp (o->name, "deletable") == 0
2870 || strcmp (o->name, "if_marked") == 0)
2871 skip_p = 1;
2873 if (skip_p)
2874 continue;
2876 for (fli = flp; fli; fli = fli->next)
2877 if (fli->f == f)
2878 break;
2879 if (! fli->started_p)
2881 fli->started_p = 1;
2883 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2884 put_mangled_filename (f, v->line.file);
2885 oprintf (f, "[] = {\n");
2888 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2891 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2892 "gt_ggc_rtab");
2894 for (v = variables; v; v = v->next)
2896 outf_p f = get_output_file_with_visibility (v->line.file);
2897 struct flist *fli;
2898 int skip_p = 1;
2899 options_p o;
2901 for (o = v->opt; o; o = o->next)
2902 if (strcmp (o->name, "deletable") == 0)
2903 skip_p = 0;
2904 else if (strcmp (o->name, "if_marked") == 0)
2905 skip_p = 1;
2907 if (skip_p)
2908 continue;
2910 for (fli = flp; fli; fli = fli->next)
2911 if (fli->f == f)
2912 break;
2913 if (! fli->started_p)
2915 fli->started_p = 1;
2917 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2918 put_mangled_filename (f, v->line.file);
2919 oprintf (f, "[] = {\n");
2922 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2923 v->name, v->name);
2926 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2927 "gt_ggc_deletable_rtab");
2929 for (v = variables; v; v = v->next)
2931 outf_p f = get_output_file_with_visibility (v->line.file);
2932 struct flist *fli;
2933 const char *if_marked = NULL;
2934 int length_p = 0;
2935 options_p o;
2937 for (o = v->opt; o; o = o->next)
2938 if (strcmp (o->name, "length") == 0)
2939 length_p = 1;
2940 else if (strcmp (o->name, "if_marked") == 0)
2941 if_marked = o->info;
2943 if (if_marked == NULL)
2944 continue;
2946 if (v->type->kind != TYPE_POINTER
2947 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2948 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2950 error_at_line (&v->line, "if_marked option used but not hash table");
2951 continue;
2954 for (fli = flp; fli; fli = fli->next)
2955 if (fli->f == f)
2956 break;
2957 if (! fli->started_p)
2959 fli->started_p = 1;
2961 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2962 put_mangled_filename (f, v->line.file);
2963 oprintf (f, "[] = {\n");
2966 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2967 v->name, length_p, &v->line, if_marked);
2970 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2971 "gt_ggc_cache_rtab");
2973 for (v = variables; v; v = v->next)
2975 outf_p f = get_output_file_with_visibility (v->line.file);
2976 struct flist *fli;
2977 int length_p = 0;
2978 int if_marked_p = 0;
2979 options_p o;
2981 for (o = v->opt; o; o = o->next)
2982 if (strcmp (o->name, "length") == 0)
2983 length_p = 1;
2984 else if (strcmp (o->name, "if_marked") == 0)
2985 if_marked_p = 1;
2987 if (! if_marked_p)
2988 continue;
2990 for (fli = flp; fli; fli = fli->next)
2991 if (fli->f == f)
2992 break;
2993 if (! fli->started_p)
2995 fli->started_p = 1;
2997 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2998 put_mangled_filename (f, v->line.file);
2999 oprintf (f, "[] = {\n");
3002 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3005 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3006 "gt_pch_cache_rtab");
3008 for (v = variables; v; v = v->next)
3010 outf_p f = get_output_file_with_visibility (v->line.file);
3011 struct flist *fli;
3012 int skip_p = 0;
3013 options_p o;
3015 for (o = v->opt; o; o = o->next)
3016 if (strcmp (o->name, "deletable") == 0
3017 || strcmp (o->name, "if_marked") == 0)
3018 skip_p = 1;
3020 if (skip_p)
3021 continue;
3023 if (! contains_scalar_p (v->type))
3024 continue;
3026 for (fli = flp; fli; fli = fli->next)
3027 if (fli->f == f)
3028 break;
3029 if (! fli->started_p)
3031 fli->started_p = 1;
3033 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3034 put_mangled_filename (f, v->line.file);
3035 oprintf (f, "[] = {\n");
3038 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3039 v->name, v->name);
3042 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3043 "gt_pch_scalar_rtab");
3047 extern int main (int argc, char **argv);
3049 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
3051 unsigned i;
3052 static struct fileloc pos = { __FILE__, __LINE__ };
3053 unsigned j;
3055 gen_rtx_next ();
3057 srcdir_len = strlen (srcdir);
3059 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3060 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3061 do_scalar_typedef ("double_int", &pos);
3062 do_scalar_typedef ("uint8", &pos);
3063 do_scalar_typedef ("jword", &pos);
3064 do_scalar_typedef ("JCF_u2", &pos);
3065 #ifdef USE_MAPPED_LOCATION
3066 do_scalar_typedef ("location_t", &pos);
3067 do_scalar_typedef ("source_locus", &pos);
3068 #endif
3069 do_scalar_typedef ("void", &pos);
3071 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3073 do_typedef ("HARD_REG_SET", create_array (
3074 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3075 "2"), &pos);
3077 for (i = 0; i < NUM_GT_FILES; i++)
3079 int dupflag = 0;
3080 /* Omit if already seen. */
3081 for (j = 0; j < i; j++)
3083 if (!strcmp (all_files[i], all_files[j]))
3085 dupflag = 1;
3086 break;
3089 if (!dupflag)
3090 parse_file (all_files[i]);
3091 #ifndef USE_MAPPED_LOCATION
3092 /* temporary kludge - gengtype doesn't handle conditionals.
3093 Manually add source_locus *after* we've processed input.h. */
3094 if (i == 0)
3095 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3096 #endif
3099 if (hit_error != 0)
3100 exit (1);
3102 set_gc_used (variables);
3104 open_base_files ();
3105 write_enum_defn (structures, param_structs);
3106 write_types (structures, param_structs, &ggc_wtd);
3107 write_types (structures, param_structs, &pch_wtd);
3108 write_local (structures, param_structs);
3109 write_roots (variables);
3110 write_rtx_next ();
3111 close_output_files ();
3113 return (hit_error != 0);