gcc/ChangeLog:
[official-gcc.git] / gcc / gengtype.c
blob515c31c4695938b55ad83165088dddd8ad9988ea
1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "bconfig.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "gengtype.h"
27 #include "gtyp-gen.h"
28 #include "errors.h"
30 /* Nonzero iff an error has occurred. */
31 static int hit_error = 0;
33 static void gen_rtx_next (void);
34 static void write_rtx_next (void);
35 static void open_base_files (void);
36 static void close_output_files (void);
38 /* Report an error at POS, printing MSG. */
40 void
41 error_at_line (struct fileloc *pos, const char *msg, ...)
43 va_list ap;
45 va_start (ap, msg);
47 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
48 vfprintf (stderr, msg, ap);
49 fputc ('\n', stderr);
50 hit_error = 1;
52 va_end (ap);
55 /* vasprintf, but produces fatal message on out-of-memory. */
56 int
57 xvasprintf (char **result, const char *format, va_list args)
59 int ret = vasprintf (result, format, args);
60 if (*result == NULL || ret < 0)
62 fputs ("gengtype: out of memory", stderr);
63 xexit (1);
65 return ret;
68 /* Wrapper for xvasprintf. */
69 char *
70 xasprintf (const char *format, ...)
72 char *result;
73 va_list ap;
75 va_start (ap, format);
76 xvasprintf (&result, format, ap);
77 va_end (ap);
78 return result;
81 /* The one and only TYPE_STRING. */
83 struct type string_type = {
84 TYPE_STRING, NULL, NULL, GC_USED, {0}
87 /* Lists of various things. */
89 static pair_p typedefs;
90 static type_p structures;
91 static type_p param_structs;
92 static pair_p variables;
94 static void do_scalar_typedef (const char *, struct fileloc *);
95 static type_p find_param_structure
96 (type_p t, type_p param[NUM_PARAM]);
97 static type_p adjust_field_tree_exp (type_p t, options_p opt);
98 static type_p adjust_field_rtx_def (type_p t, options_p opt);
100 /* Define S as a typedef to T at POS. */
102 void
103 do_typedef (const char *s, type_p t, struct fileloc *pos)
105 pair_p p;
107 for (p = typedefs; p != NULL; p = p->next)
108 if (strcmp (p->name, s) == 0)
110 if (p->type != t)
112 error_at_line (pos, "type `%s' previously defined", s);
113 error_at_line (&p->line, "previously defined here");
115 return;
118 p = XNEW (struct pair);
119 p->next = typedefs;
120 p->name = s;
121 p->type = t;
122 p->line = *pos;
123 typedefs = p;
126 /* Define S as a typename of a scalar. */
128 static void
129 do_scalar_typedef (const char *s, struct fileloc *pos)
131 do_typedef (s, create_scalar_type (s, strlen (s)), pos);
134 /* Return the type previously defined for S. Use POS to report errors. */
136 type_p
137 resolve_typedef (const char *s, struct fileloc *pos)
139 pair_p p;
140 for (p = typedefs; p != NULL; p = p->next)
141 if (strcmp (p->name, s) == 0)
142 return p->type;
143 error_at_line (pos, "unidentified type `%s'", s);
144 return create_scalar_type ("char", 4);
147 /* Create and return a new structure with tag NAME (or a union iff
148 ISUNION is nonzero), at POS with fields FIELDS and options O. */
150 type_p
151 new_structure (const char *name, int isunion, struct fileloc *pos,
152 pair_p fields, options_p o)
154 type_p si;
155 type_p s = NULL;
156 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
158 for (si = structures; si != NULL; si = si->next)
159 if (strcmp (name, si->u.s.tag) == 0
160 && UNION_P (si) == isunion)
162 type_p ls = NULL;
163 if (si->kind == TYPE_LANG_STRUCT)
165 ls = si;
167 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
168 if (si->u.s.bitmap == bitmap)
169 s = si;
171 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
173 ls = si;
174 si = XCNEW (struct type);
175 memcpy (si, ls, sizeof (struct type));
176 ls->kind = TYPE_LANG_STRUCT;
177 ls->u.s.lang_struct = si;
178 ls->u.s.fields = NULL;
179 si->next = NULL;
180 si->pointer_to = NULL;
181 si->u.s.lang_struct = ls;
183 else
184 s = si;
186 if (ls != NULL && s == NULL)
188 s = XCNEW (struct type);
189 s->next = ls->u.s.lang_struct;
190 ls->u.s.lang_struct = s;
191 s->u.s.lang_struct = ls;
193 break;
196 if (s == NULL)
198 s = XCNEW (struct type);
199 s->next = structures;
200 structures = s;
203 if (s->u.s.line.file != NULL
204 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
206 error_at_line (pos, "duplicate structure definition");
207 error_at_line (&s->u.s.line, "previous definition here");
210 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
211 s->u.s.tag = name;
212 s->u.s.line = *pos;
213 s->u.s.fields = fields;
214 s->u.s.opt = o;
215 s->u.s.bitmap = bitmap;
216 if (s->u.s.lang_struct)
217 s->u.s.lang_struct->u.s.bitmap |= bitmap;
219 return s;
222 /* Return the previously-defined structure with tag NAME (or a union
223 iff ISUNION is nonzero), or a new empty structure or union if none
224 was defined previously. */
226 type_p
227 find_structure (const char *name, int isunion)
229 type_p s;
231 for (s = structures; s != NULL; s = s->next)
232 if (strcmp (name, s->u.s.tag) == 0
233 && UNION_P (s) == isunion)
234 return s;
236 s = XCNEW (struct type);
237 s->next = structures;
238 structures = s;
239 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
240 s->u.s.tag = name;
241 structures = s;
242 return s;
245 /* Return the previously-defined parameterized structure for structure
246 T and parameters PARAM, or a new parameterized empty structure or
247 union if none was defined previously. */
249 static type_p
250 find_param_structure (type_p t, type_p param[NUM_PARAM])
252 type_p res;
254 for (res = param_structs; res; res = res->next)
255 if (res->u.param_struct.stru == t
256 && memcmp (res->u.param_struct.param, param,
257 sizeof (type_p) * NUM_PARAM) == 0)
258 break;
259 if (res == NULL)
261 res = XCNEW (struct type);
262 res->kind = TYPE_PARAM_STRUCT;
263 res->next = param_structs;
264 param_structs = res;
265 res->u.param_struct.stru = t;
266 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
268 return res;
271 /* Return a scalar type with name NAME. */
273 type_p
274 create_scalar_type (const char *name, size_t name_len)
276 type_p r = XCNEW (struct type);
277 r->kind = TYPE_SCALAR;
278 r->u.sc = (char *) xmemdup (name, name_len, name_len + 1);
279 return r;
282 /* Return a pointer to T. */
284 type_p
285 create_pointer (type_p t)
287 if (! t->pointer_to)
289 type_p r = XCNEW (struct type);
290 r->kind = TYPE_POINTER;
291 r->u.p = t;
292 t->pointer_to = r;
294 return t->pointer_to;
297 /* Return an array of length LEN. */
299 type_p
300 create_array (type_p t, const char *len)
302 type_p v;
304 v = XCNEW (struct type);
305 v->kind = TYPE_ARRAY;
306 v->u.a.p = t;
307 v->u.a.len = len;
308 return v;
311 /* Return an options structure with name NAME and info INFO. NEXT is the
312 next option in the chain. */
314 options_p
315 create_option (options_p next, const char *name, const void *info)
317 options_p o = XNEW (struct options);
318 o->next = next;
319 o->name = name;
320 o->info = (const char*) info;
321 return o;
324 /* Add a variable named S of type T with options O defined at POS,
325 to `variables'. */
327 void
328 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
330 pair_p n;
331 n = XNEW (struct pair);
332 n->name = s;
333 n->type = t;
334 n->line = *pos;
335 n->opt = o;
336 n->next = variables;
337 variables = n;
340 /* Create a fake field with the given type and name. NEXT is the next
341 field in the chain. */
343 static pair_p
344 create_field (pair_p next, type_p type, const char *name)
346 pair_p field;
348 field = XNEW (struct pair);
349 field->next = next;
350 field->type = type;
351 field->name = name;
352 field->opt = NULL;
353 field->line.file = __FILE__;
354 field->line.line = __LINE__;
355 return field;
358 /* Like create_field, but the field is only valid when condition COND
359 is true. */
361 static pair_p
362 create_optional_field (pair_p next, type_p type, const char *name,
363 const char *cond)
365 static int id = 1;
366 pair_p union_fields, field;
367 type_p union_type;
369 /* Create a fake union type with a single nameless field of type TYPE.
370 The field has a tag of "1". This allows us to make the presence
371 of a field of type TYPE depend on some boolean "desc" being true. */
372 union_fields = create_field (NULL, type, "");
373 union_fields->opt = create_option (union_fields->opt, "dot", "");
374 union_fields->opt = create_option (union_fields->opt, "tag", "1");
375 union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
376 &lexer_line, union_fields, NULL);
378 /* Create the field and give it the new fake union type. Add a "desc"
379 tag that specifies the condition under which the field is valid. */
380 field = create_field (next, union_type, name);
381 field->opt = create_option (field->opt, "desc", cond);
382 return field;
385 /* We don't care how long a CONST_DOUBLE is. */
386 #define CONST_DOUBLE_FORMAT "ww"
387 /* We don't want to see codes that are only for generator files. */
388 #undef GENERATOR_FILE
390 enum rtx_code {
391 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
392 #include "rtl.def"
393 #undef DEF_RTL_EXPR
394 NUM_RTX_CODE
397 static const char * const rtx_name[NUM_RTX_CODE] = {
398 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
399 #include "rtl.def"
400 #undef DEF_RTL_EXPR
403 static const char * const rtx_format[NUM_RTX_CODE] = {
404 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
405 #include "rtl.def"
406 #undef DEF_RTL_EXPR
409 static int rtx_next_new[NUM_RTX_CODE];
411 /* We also need codes and names for insn notes (not register notes).
412 Note that we do *not* bias the note values here. */
413 enum insn_note {
414 #define DEF_INSN_NOTE(NAME) NAME,
415 #include "insn-notes.def"
416 #undef DEF_INSN_NOTE
418 NOTE_INSN_MAX
421 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
422 default field for line number notes. */
423 static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
424 #define DEF_INSN_NOTE(NAME) #NAME,
425 #include "insn-notes.def"
426 #undef DEF_INSN_NOTE
429 #undef CONST_DOUBLE_FORMAT
430 #define GENERATOR_FILE
432 /* Generate the contents of the rtx_next array. This really doesn't belong
433 in gengtype at all, but it's needed for adjust_field_rtx_def. */
435 static void
436 gen_rtx_next (void)
438 int i;
439 for (i = 0; i < NUM_RTX_CODE; i++)
441 int k;
443 rtx_next_new[i] = -1;
444 if (strncmp (rtx_format[i], "iuu", 3) == 0)
445 rtx_next_new[i] = 2;
446 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
447 rtx_next_new[i] = 1;
448 else
449 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
450 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
451 rtx_next_new[i] = k;
455 /* Write out the contents of the rtx_next array. */
456 static void
457 write_rtx_next (void)
459 outf_p f = get_output_file_with_visibility (NULL);
460 int i;
462 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
463 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
464 for (i = 0; i < NUM_RTX_CODE; i++)
465 if (rtx_next_new[i] == -1)
466 oprintf (f, " 0,\n");
467 else
468 oprintf (f,
469 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
470 rtx_next_new[i]);
471 oprintf (f, "};\n");
474 /* Handle `special("rtx_def")'. This is a special case for field
475 `fld' of struct rtx_def, which is an array of unions whose values
476 are based in a complex way on the type of RTL. */
478 static type_p
479 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
481 pair_p flds = NULL;
482 options_p nodot;
483 int i;
484 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
485 type_p bitmap_tp, basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
487 if (t->kind != TYPE_UNION)
489 error_at_line (&lexer_line,
490 "special `rtx_def' must be applied to a union");
491 return &string_type;
494 nodot = create_option (NULL, "dot", "");
496 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
497 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
498 tree_tp = create_pointer (find_structure ("tree_node", 1));
499 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
500 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
501 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
502 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
503 constant_tp = create_pointer (find_structure ("constant_descriptor_rtx", 0));
504 scalar_tp = create_scalar_type ("rtunion scalar", 14);
507 pair_p note_flds = NULL;
508 int c;
510 for (c = 0; c <= NOTE_INSN_MAX; c++)
512 switch (c)
514 case NOTE_INSN_MAX:
515 note_flds = create_field (note_flds, &string_type, "rt_str");
516 break;
518 case NOTE_INSN_BLOCK_BEG:
519 case NOTE_INSN_BLOCK_END:
520 note_flds = create_field (note_flds, tree_tp, "rt_tree");
521 break;
523 case NOTE_INSN_VAR_LOCATION:
524 note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
525 break;
527 default:
528 note_flds = create_field (note_flds, scalar_tp, "rt_int");
529 break;
531 /* NOTE_INSN_MAX is used as the default field for line
532 number notes. */
533 if (c == NOTE_INSN_MAX)
534 note_flds->opt = create_option (nodot, "default", "");
535 else
536 note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
538 note_union_tp = new_structure ("rtx_def_note_subunion", 1,
539 &lexer_line, note_flds, NULL);
541 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */
543 pair_p sym_flds;
545 sym_flds = create_field (NULL, tree_tp, "rt_tree");
546 sym_flds->opt = create_option (nodot, "default", "");
548 sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
549 sym_flds->opt = create_option (nodot, "tag", "1");
551 symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
552 &lexer_line, sym_flds, NULL);
554 for (i = 0; i < NUM_RTX_CODE; i++)
556 pair_p subfields = NULL;
557 size_t aindex, nmindex;
558 const char *sname;
559 type_p substruct;
560 char *ftag;
562 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
564 type_p t;
565 const char *subname;
567 switch (rtx_format[i][aindex])
569 case '*':
570 case 'i':
571 case 'n':
572 case 'w':
573 t = scalar_tp;
574 subname = "rt_int";
575 break;
577 case '0':
578 if (i == MEM && aindex == 1)
579 t = mem_attrs_tp, subname = "rt_mem";
580 else if (i == JUMP_INSN && aindex == 9)
581 t = rtx_tp, subname = "rt_rtx";
582 else if (i == CODE_LABEL && aindex == 4)
583 t = scalar_tp, subname = "rt_int";
584 else if (i == CODE_LABEL && aindex == 5)
585 t = rtx_tp, subname = "rt_rtx";
586 else if (i == LABEL_REF
587 && (aindex == 1 || aindex == 2))
588 t = rtx_tp, subname = "rt_rtx";
589 else if (i == NOTE && aindex == 4)
590 t = note_union_tp, subname = "";
591 else if (i == NOTE && aindex >= 7)
592 t = scalar_tp, subname = "rt_int";
593 else if (i == ADDR_DIFF_VEC && aindex == 4)
594 t = scalar_tp, subname = "rt_int";
595 else if (i == VALUE && aindex == 0)
596 t = scalar_tp, subname = "rt_int";
597 else if (i == REG && aindex == 1)
598 t = scalar_tp, subname = "rt_int";
599 else if (i == REG && aindex == 2)
600 t = reg_attrs_tp, subname = "rt_reg";
601 else if (i == SCRATCH && aindex == 0)
602 t = scalar_tp, subname = "rt_int";
603 else if (i == SYMBOL_REF && aindex == 1)
604 t = scalar_tp, subname = "rt_int";
605 else if (i == SYMBOL_REF && aindex == 2)
606 t = symbol_union_tp, subname = "";
607 else if (i == BARRIER && aindex >= 3)
608 t = scalar_tp, subname = "rt_int";
609 else
611 error_at_line (&lexer_line,
612 "rtx type `%s' has `0' in position %lu, can't handle",
613 rtx_name[i], (unsigned long) aindex);
614 t = &string_type;
615 subname = "rt_int";
617 break;
619 case 's':
620 case 'S':
621 case 'T':
622 t = &string_type;
623 subname = "rt_str";
624 break;
626 case 'e':
627 case 'u':
628 t = rtx_tp;
629 subname = "rt_rtx";
630 break;
632 case 'E':
633 case 'V':
634 t = rtvec_tp;
635 subname = "rt_rtvec";
636 break;
638 case 't':
639 t = tree_tp;
640 subname = "rt_tree";
641 break;
643 case 'b':
644 t = bitmap_tp;
645 subname = "rt_bit";
646 break;
648 case 'B':
649 t = basic_block_tp;
650 subname = "rt_bb";
651 break;
653 default:
654 error_at_line (&lexer_line,
655 "rtx type `%s' has `%c' in position %lu, can't handle",
656 rtx_name[i], rtx_format[i][aindex],
657 (unsigned long)aindex);
658 t = &string_type;
659 subname = "rt_int";
660 break;
663 subfields = create_field (subfields, t,
664 xasprintf (".fld[%lu].%s",
665 (unsigned long) aindex,
666 subname));
667 subfields->opt = nodot;
668 if (t == note_union_tp)
669 subfields->opt = create_option (subfields->opt, "desc",
670 "NOTE_LINE_NUMBER (&%0)");
671 if (t == symbol_union_tp)
672 subfields->opt = create_option (subfields->opt, "desc",
673 "CONSTANT_POOL_ADDRESS_P (&%0)");
676 if (i == SYMBOL_REF)
678 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
679 type_p field_tp = find_structure ("block_symbol", 0);
680 subfields
681 = create_optional_field (subfields, field_tp, "block_sym",
682 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
685 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
686 substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
688 ftag = xstrdup (rtx_name[i]);
689 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
690 ftag[nmindex] = TOUPPER (ftag[nmindex]);
692 flds = create_field (flds, substruct, "");
693 flds->opt = create_option (nodot, "tag", ftag);
696 return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
699 /* Handle `special("tree_exp")'. This is a special case for
700 field `operands' of struct tree_exp, which although it claims to contain
701 pointers to trees, actually sometimes contains pointers to RTL too.
702 Passed T, the old type of the field, and OPT its options. Returns
703 a new type for the field. */
705 static type_p
706 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
708 pair_p flds;
709 options_p nodot;
711 if (t->kind != TYPE_ARRAY)
713 error_at_line (&lexer_line,
714 "special `tree_exp' must be applied to an array");
715 return &string_type;
718 nodot = create_option (NULL, "dot", "");
720 flds = create_field (NULL, t, "");
721 flds->opt = create_option (nodot, "length",
722 "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))");
723 flds->opt = create_option (flds->opt, "default", "");
725 return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
728 /* Perform any special processing on a type T, about to become the type
729 of a field. Return the appropriate type for the field.
730 At present:
731 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
732 - Similarly for arrays of pointer-to-char;
733 - Converts structures for which a parameter is provided to
734 TYPE_PARAM_STRUCT;
735 - Handles "special" options.
738 type_p
739 adjust_field_type (type_p t, options_p opt)
741 int length_p = 0;
742 const int pointer_p = t->kind == TYPE_POINTER;
743 type_p params[NUM_PARAM];
744 int params_p = 0;
745 int i;
747 for (i = 0; i < NUM_PARAM; i++)
748 params[i] = NULL;
750 for (; opt; opt = opt->next)
751 if (strcmp (opt->name, "length") == 0)
752 length_p = 1;
753 else if (strcmp (opt->name, "param_is") == 0
754 || (strncmp (opt->name, "param", 5) == 0
755 && ISDIGIT (opt->name[5])
756 && strcmp (opt->name + 6, "_is") == 0))
758 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
760 if (! UNION_OR_STRUCT_P (t)
761 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
763 error_at_line (&lexer_line,
764 "option `%s' may only be applied to structures or structure pointers",
765 opt->name);
766 return t;
769 params_p = 1;
770 if (params[num] != NULL)
771 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
772 if (! ISDIGIT (opt->name[5]))
773 params[num] = create_pointer ((type_p) opt->info);
774 else
775 params[num] = (type_p) opt->info;
777 else if (strcmp (opt->name, "special") == 0)
779 const char *special_name = opt->info;
780 if (strcmp (special_name, "tree_exp") == 0)
781 t = adjust_field_tree_exp (t, opt);
782 else if (strcmp (special_name, "rtx_def") == 0)
783 t = adjust_field_rtx_def (t, opt);
784 else
785 error_at_line (&lexer_line, "unknown special `%s'", special_name);
788 if (params_p)
790 type_p realt;
792 if (pointer_p)
793 t = t->u.p;
794 realt = find_param_structure (t, params);
795 t = pointer_p ? create_pointer (realt) : realt;
798 if (! length_p
799 && pointer_p
800 && t->u.p->kind == TYPE_SCALAR
801 && (strcmp (t->u.p->u.sc, "char") == 0
802 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
803 return &string_type;
804 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
805 && t->u.a.p->u.p->kind == TYPE_SCALAR
806 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
807 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
808 return create_array (&string_type, t->u.a.len);
810 return t;
813 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
814 and information about the correspondence between token types and fields
815 in TYPEINFO. POS is used for error messages. */
817 void
818 note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
819 struct fileloc *pos)
821 pair_p p;
822 pair_p *p_p;
824 for (p = typeinfo; p; p = p->next)
826 pair_p m;
828 if (p->name == NULL)
829 continue;
831 if (p->type == (type_p) 1)
833 pair_p pp;
834 int ok = 0;
836 for (pp = typeinfo; pp; pp = pp->next)
837 if (pp->type != (type_p) 1
838 && strcmp (pp->opt->info, p->opt->info) == 0)
840 ok = 1;
841 break;
843 if (! ok)
844 continue;
847 for (m = fields; m; m = m->next)
848 if (strcmp (m->name, p->name) == 0)
849 p->type = m->type;
850 if (p->type == NULL)
852 error_at_line (&p->line,
853 "couldn't match fieldname `%s'", p->name);
854 p->name = NULL;
858 p_p = &typeinfo;
859 while (*p_p)
861 pair_p p = *p_p;
863 if (p->name == NULL
864 || p->type == (type_p) 1)
865 *p_p = p->next;
866 else
867 p_p = &p->next;
870 do_typedef ("YYSTYPE", new_structure ("yy_union", 1, pos, typeinfo, o), pos);
873 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
874 static void set_gc_used (pair_p);
876 /* Handle OPT for set_gc_used_type. */
878 static void
879 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
880 int *pass_param, int *length, int *skip, type_p *nested_ptr)
882 options_p o;
883 for (o = opt; o; o = o->next)
884 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
885 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
886 else if (strcmp (o->name, "maybe_undef") == 0)
887 *maybe_undef = 1;
888 else if (strcmp (o->name, "use_params") == 0)
889 *pass_param = 1;
890 else if (strcmp (o->name, "length") == 0)
891 *length = 1;
892 else if (strcmp (o->name, "skip") == 0)
893 *skip = 1;
894 else if (strcmp (o->name, "nested_ptr") == 0)
895 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
898 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
900 static void
901 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
903 if (t->gc_used >= level)
904 return;
906 t->gc_used = level;
908 switch (t->kind)
910 case TYPE_STRUCT:
911 case TYPE_UNION:
913 pair_p f;
914 int dummy;
915 type_p dummy2;
917 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
918 &dummy2);
920 for (f = t->u.s.fields; f; f = f->next)
922 int maybe_undef = 0;
923 int pass_param = 0;
924 int length = 0;
925 int skip = 0;
926 type_p nested_ptr = NULL;
927 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
928 &length, &skip, &nested_ptr);
930 if (nested_ptr && f->type->kind == TYPE_POINTER)
931 set_gc_used_type (nested_ptr, GC_POINTED_TO,
932 pass_param ? param : NULL);
933 else if (length && f->type->kind == TYPE_POINTER)
934 set_gc_used_type (f->type->u.p, GC_USED, NULL);
935 else if (maybe_undef && f->type->kind == TYPE_POINTER)
936 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
937 else if (pass_param && f->type->kind == TYPE_POINTER && param)
938 set_gc_used_type (find_param_structure (f->type->u.p, param),
939 GC_POINTED_TO, NULL);
940 else if (skip)
941 ; /* target type is not used through this field */
942 else
943 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
945 break;
948 case TYPE_POINTER:
949 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
950 break;
952 case TYPE_ARRAY:
953 set_gc_used_type (t->u.a.p, GC_USED, param);
954 break;
956 case TYPE_LANG_STRUCT:
957 for (t = t->u.s.lang_struct; t; t = t->next)
958 set_gc_used_type (t, level, param);
959 break;
961 case TYPE_PARAM_STRUCT:
963 int i;
964 for (i = 0; i < NUM_PARAM; i++)
965 if (t->u.param_struct.param[i] != 0)
966 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
968 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
969 level = GC_POINTED_TO;
970 else
971 level = GC_USED;
972 t->u.param_struct.stru->gc_used = GC_UNUSED;
973 set_gc_used_type (t->u.param_struct.stru, level,
974 t->u.param_struct.param);
975 break;
977 default:
978 break;
982 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
984 static void
985 set_gc_used (pair_p variables)
987 pair_p p;
988 for (p = variables; p; p = p->next)
989 set_gc_used_type (p->type, GC_USED, NULL);
992 /* File mapping routines. For each input file, there is one output .c file
993 (but some output files have many input files), and there is one .h file
994 for the whole build. */
996 /* The list of output files. */
997 static outf_p output_files;
999 /* The output header file that is included into pretty much every
1000 source file. */
1001 static outf_p header_file;
1003 /* Number of files specified in gtfiles. */
1004 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1006 /* Number of files in the language files array. */
1007 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1009 /* Length of srcdir name. */
1010 static int srcdir_len = 0;
1012 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1013 outf_p base_files[NUM_BASE_FILES];
1015 static outf_p create_file (const char *, const char *);
1016 static const char * get_file_basename (const char *);
1018 /* Create and return an outf_p for a new file for NAME, to be called
1019 ONAME. */
1021 static outf_p
1022 create_file (const char *name, const char *oname)
1024 static const char *const hdr[] = {
1025 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
1026 "\n",
1027 "This file is part of GCC.\n",
1028 "\n",
1029 "GCC is free software; you can redistribute it and/or modify it under\n",
1030 "the terms of the GNU General Public License as published by the Free\n",
1031 "Software Foundation; either version 2, or (at your option) any later\n",
1032 "version.\n",
1033 "\n",
1034 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1035 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1036 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1037 "for more details.\n",
1038 "\n",
1039 "You should have received a copy of the GNU General Public License\n",
1040 "along with GCC; see the file COPYING. If not, write to the Free\n",
1041 "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1042 "02110-1301, USA. */\n",
1043 "\n",
1044 "/* This file is machine generated. Do not edit. */\n"
1046 outf_p f;
1047 size_t i;
1049 f = XCNEW (struct outf);
1050 f->next = output_files;
1051 f->name = oname;
1052 output_files = f;
1054 oprintf (f, "/* Type information for %s.\n", name);
1055 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1056 oprintf (f, "%s", hdr[i]);
1057 return f;
1060 /* Print, like fprintf, to O. */
1061 void
1062 oprintf (outf_p o, const char *format, ...)
1064 char *s;
1065 size_t slength;
1066 va_list ap;
1068 va_start (ap, format);
1069 slength = xvasprintf (&s, format, ap);
1071 if (o->bufused + slength > o->buflength)
1073 size_t new_len = o->buflength;
1074 if (new_len == 0)
1075 new_len = 1024;
1076 do {
1077 new_len *= 2;
1078 } while (o->bufused + slength >= new_len);
1079 o->buf = XRESIZEVEC (char, o->buf, new_len);
1080 o->buflength = new_len;
1082 memcpy (o->buf + o->bufused, s, slength);
1083 o->bufused += slength;
1084 free (s);
1085 va_end (ap);
1088 /* Open the global header file and the language-specific header files. */
1090 static void
1091 open_base_files (void)
1093 size_t i;
1095 header_file = create_file ("GCC", "gtype-desc.h");
1097 for (i = 0; i < NUM_BASE_FILES; i++)
1098 base_files[i] = create_file (lang_dir_names[i],
1099 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1101 /* gtype-desc.c is a little special, so we create it here. */
1103 /* The order of files here matters very much. */
1104 static const char *const ifiles [] = {
1105 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1106 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1107 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1108 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1109 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1110 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1111 "cfglayout.h", "except.h", "output.h", NULL
1113 const char *const *ifp;
1114 outf_p gtype_desc_c;
1116 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1117 for (ifp = ifiles; *ifp; ifp++)
1118 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1122 /* Determine the pathname to F relative to $(srcdir). */
1124 static const char *
1125 get_file_basename (const char *f)
1127 const char *basename;
1128 unsigned i;
1130 basename = strrchr (f, '/');
1132 if (!basename)
1133 return f;
1135 basename++;
1137 for (i = 1; i < NUM_BASE_FILES; i++)
1139 const char * s1;
1140 const char * s2;
1141 int l1;
1142 int l2;
1143 s1 = basename - strlen (lang_dir_names [i]) - 1;
1144 s2 = lang_dir_names [i];
1145 l1 = strlen (s1);
1146 l2 = strlen (s2);
1147 if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1149 basename -= l2 + 1;
1150 if ((basename - f - 1) != srcdir_len)
1151 fatal ("filename `%s' should be preceded by $srcdir", f);
1152 break;
1156 return basename;
1159 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1160 INPUT_FILE is used by <lang>.
1162 This function should be written to assume that a file _is_ used
1163 if the situation is unclear. If it wrongly assumes a file _is_ used,
1164 a linker error will result. If it wrongly assumes a file _is not_ used,
1165 some GC roots may be missed, which is a much harder-to-debug problem. */
1167 unsigned
1168 get_base_file_bitmap (const char *input_file)
1170 const char *basename = get_file_basename (input_file);
1171 const char *slashpos = strchr (basename, '/');
1172 unsigned j;
1173 unsigned k;
1174 unsigned bitmap;
1176 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1177 it belongs to the corresponding language. The file may belong to other
1178 languages as well (which is checked for below). */
1180 if (slashpos)
1182 size_t i;
1183 for (i = 1; i < NUM_BASE_FILES; i++)
1184 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1185 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1187 /* It's in a language directory, set that language. */
1188 bitmap = 1 << i;
1192 /* If it's in any config-lang.in, then set for the languages
1193 specified. */
1195 bitmap = 0;
1197 for (j = 0; j < NUM_LANG_FILES; j++)
1199 if (!strcmp(input_file, lang_files[j]))
1201 for (k = 0; k < NUM_BASE_FILES; k++)
1203 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1204 bitmap |= (1 << k);
1209 /* Otherwise, set all languages. */
1210 if (!bitmap)
1211 bitmap = (1 << NUM_BASE_FILES) - 1;
1213 return bitmap;
1216 /* An output file, suitable for definitions, that can see declarations
1217 made in INPUT_FILE and is linked into every language that uses
1218 INPUT_FILE. */
1220 outf_p
1221 get_output_file_with_visibility (const char *input_file)
1223 outf_p r;
1224 size_t len;
1225 const char *basename;
1226 const char *for_name;
1227 const char *output_name;
1229 /* This can happen when we need a file with visibility on a
1230 structure that we've never seen. We have to just hope that it's
1231 globally visible. */
1232 if (input_file == NULL)
1233 input_file = "system.h";
1235 /* Determine the output file name. */
1236 basename = get_file_basename (input_file);
1238 len = strlen (basename);
1239 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1240 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1241 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1243 char *s;
1245 output_name = s = xasprintf ("gt-%s", basename);
1246 for (; *s != '.'; s++)
1247 if (! ISALNUM (*s) && *s != '-')
1248 *s = '-';
1249 memcpy (s, ".h", sizeof (".h"));
1250 for_name = basename;
1252 /* Some headers get used by more than one front-end; hence, it
1253 would be inappropriate to spew them out to a single gtype-<lang>.h
1254 (and gengtype doesn't know how to direct spewage into multiple
1255 gtype-<lang>.h headers at this time). Instead, we pair up these
1256 headers with source files (and their special purpose gt-*.h headers). */
1257 else if (strcmp (basename, "c-common.h") == 0)
1258 output_name = "gt-c-common.h", for_name = "c-common.c";
1259 else if (strcmp (basename, "c-tree.h") == 0)
1260 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1261 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1262 && strcmp (basename + 3, "cp-tree.h") == 0)
1263 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1264 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1265 && strcmp (basename + 3, "decl.h") == 0)
1266 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1267 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1268 && strcmp (basename + 3, "name-lookup.h") == 0)
1269 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1270 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1271 && strcmp (basename + 5, "objc-act.h") == 0)
1272 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1273 else
1275 size_t i;
1277 for (i = 0; i < NUM_BASE_FILES; i++)
1278 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1279 && basename[strlen(lang_dir_names[i])] == '/')
1280 return base_files[i];
1282 output_name = "gtype-desc.c";
1283 for_name = NULL;
1286 /* Look through to see if we've ever seen this output filename before. */
1287 for (r = output_files; r; r = r->next)
1288 if (strcmp (r->name, output_name) == 0)
1289 return r;
1291 /* If not, create it. */
1292 r = create_file (for_name, output_name);
1294 return r;
1297 /* The name of an output file, suitable for definitions, that can see
1298 declarations made in INPUT_FILE and is linked into every language
1299 that uses INPUT_FILE. */
1301 const char *
1302 get_output_file_name (const char *input_file)
1304 return get_output_file_with_visibility (input_file)->name;
1307 /* Copy the output to its final destination,
1308 but don't unnecessarily change modification times. */
1310 static void
1311 close_output_files (void)
1313 outf_p of;
1315 for (of = output_files; of; of = of->next)
1317 FILE * newfile;
1319 newfile = fopen (of->name, "r");
1320 if (newfile != NULL )
1322 int no_write_p;
1323 size_t i;
1325 for (i = 0; i < of->bufused; i++)
1327 int ch;
1328 ch = fgetc (newfile);
1329 if (ch == EOF || ch != (unsigned char) of->buf[i])
1330 break;
1332 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1333 fclose (newfile);
1335 if (no_write_p)
1336 continue;
1339 newfile = fopen (of->name, "w");
1340 if (newfile == NULL)
1342 perror ("opening output file");
1343 exit (1);
1345 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1347 perror ("writing output file");
1348 exit (1);
1350 if (fclose (newfile) != 0)
1352 perror ("closing output file");
1353 exit (1);
1358 struct flist {
1359 struct flist *next;
1360 int started_p;
1361 const char *name;
1362 outf_p f;
1365 struct walk_type_data;
1367 /* For scalars and strings, given the item in 'val'.
1368 For structures, given a pointer to the item in 'val'.
1369 For misc. pointers, given the item in 'val'.
1371 typedef void (*process_field_fn)
1372 (type_p f, const struct walk_type_data *p);
1373 typedef void (*func_name_fn)
1374 (type_p s, const struct walk_type_data *p);
1376 /* Parameters for write_types. */
1378 struct write_types_data
1380 const char *prefix;
1381 const char *param_prefix;
1382 const char *subfield_marker_routine;
1383 const char *marker_routine;
1384 const char *reorder_note_routine;
1385 const char *comment;
1386 int skip_hooks; /* skip hook generation if non zero */
1389 static void output_escaped_param (struct walk_type_data *d,
1390 const char *, const char *);
1391 static void output_mangled_typename (outf_p, type_p);
1392 static void walk_type (type_p t, struct walk_type_data *d);
1393 static void write_func_for_structure
1394 (type_p orig_s, type_p s, type_p * param,
1395 const struct write_types_data *wtd);
1396 static void write_types_process_field
1397 (type_p f, const struct walk_type_data *d);
1398 static void write_types (type_p structures,
1399 type_p param_structs,
1400 const struct write_types_data *wtd);
1401 static void write_types_local_process_field
1402 (type_p f, const struct walk_type_data *d);
1403 static void write_local_func_for_structure
1404 (type_p orig_s, type_p s, type_p * param);
1405 static void write_local (type_p structures,
1406 type_p param_structs);
1407 static void write_enum_defn (type_p structures, type_p param_structs);
1408 static int contains_scalar_p (type_p t);
1409 static void put_mangled_filename (outf_p , const char *);
1410 static void finish_root_table (struct flist *flp, const char *pfx,
1411 const char *tname, const char *lastname,
1412 const char *name);
1413 static void write_root (outf_p , pair_p, type_p, const char *, int,
1414 struct fileloc *, const char *);
1415 static void write_array (outf_p f, pair_p v,
1416 const struct write_types_data *wtd);
1417 static void write_roots (pair_p);
1419 /* Parameters for walk_type. */
1421 struct walk_type_data
1423 process_field_fn process_field;
1424 const void *cookie;
1425 outf_p of;
1426 options_p opt;
1427 const char *val;
1428 const char *prev_val[4];
1429 int indent;
1430 int counter;
1431 struct fileloc *line;
1432 lang_bitmap bitmap;
1433 type_p *param;
1434 int used_length;
1435 type_p orig_s;
1436 const char *reorder_fn;
1437 bool needs_cast_p;
1438 bool fn_wants_lvalue;
1441 /* Print a mangled name representing T to OF. */
1443 static void
1444 output_mangled_typename (outf_p of, type_p t)
1446 if (t == NULL)
1447 oprintf (of, "Z");
1448 else switch (t->kind)
1450 case TYPE_POINTER:
1451 oprintf (of, "P");
1452 output_mangled_typename (of, t->u.p);
1453 break;
1454 case TYPE_SCALAR:
1455 oprintf (of, "I");
1456 break;
1457 case TYPE_STRING:
1458 oprintf (of, "S");
1459 break;
1460 case TYPE_STRUCT:
1461 case TYPE_UNION:
1462 case TYPE_LANG_STRUCT:
1463 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1464 break;
1465 case TYPE_PARAM_STRUCT:
1467 int i;
1468 for (i = 0; i < NUM_PARAM; i++)
1469 if (t->u.param_struct.param[i] != NULL)
1470 output_mangled_typename (of, t->u.param_struct.param[i]);
1471 output_mangled_typename (of, t->u.param_struct.stru);
1473 break;
1474 case TYPE_ARRAY:
1475 gcc_unreachable ();
1479 /* Print PARAM to D->OF processing escapes. D->VAL references the
1480 current object, D->PREV_VAL the object containing the current
1481 object, ONAME is the name of the option and D->LINE is used to
1482 print error messages. */
1484 static void
1485 output_escaped_param (struct walk_type_data *d, const char *param,
1486 const char *oname)
1488 const char *p;
1490 for (p = param; *p; p++)
1491 if (*p != '%')
1492 oprintf (d->of, "%c", *p);
1493 else switch (*++p)
1495 case 'h':
1496 oprintf (d->of, "(%s)", d->prev_val[2]);
1497 break;
1498 case '0':
1499 oprintf (d->of, "(%s)", d->prev_val[0]);
1500 break;
1501 case '1':
1502 oprintf (d->of, "(%s)", d->prev_val[1]);
1503 break;
1504 case 'a':
1506 const char *pp = d->val + strlen (d->val);
1507 while (pp[-1] == ']')
1508 while (*pp != '[')
1509 pp--;
1510 oprintf (d->of, "%s", pp);
1512 break;
1513 default:
1514 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1515 oname, '%', *p);
1519 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1520 which is of type T. Write code to D->OF to constrain execution (at
1521 the point that D->PROCESS_FIELD is called) to the appropriate
1522 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1523 pointers to those objects. D->PREV_VAL lists the objects
1524 containing the current object, D->OPT is a list of options to
1525 apply, D->INDENT is the current indentation level, D->LINE is used
1526 to print error messages, D->BITMAP indicates which languages to
1527 print the structure for, and D->PARAM is the current parameter
1528 (from an enclosing param_is option). */
1530 static void
1531 walk_type (type_p t, struct walk_type_data *d)
1533 const char *length = NULL;
1534 const char *desc = NULL;
1535 int maybe_undef_p = 0;
1536 int use_param_num = -1;
1537 int use_params_p = 0;
1538 options_p oo;
1539 const struct nested_ptr_data *nested_ptr_d = NULL;
1541 d->needs_cast_p = false;
1542 for (oo = d->opt; oo; oo = oo->next)
1543 if (strcmp (oo->name, "length") == 0)
1544 length = oo->info;
1545 else if (strcmp (oo->name, "maybe_undef") == 0)
1546 maybe_undef_p = 1;
1547 else if (strncmp (oo->name, "use_param", 9) == 0
1548 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1549 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1550 else if (strcmp (oo->name, "use_params") == 0)
1551 use_params_p = 1;
1552 else if (strcmp (oo->name, "desc") == 0)
1553 desc = oo->info;
1554 else if (strcmp (oo->name, "mark_hook") == 0)
1556 else if (strcmp (oo->name, "nested_ptr") == 0)
1557 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1558 else if (strcmp (oo->name, "dot") == 0)
1560 else if (strcmp (oo->name, "tag") == 0)
1562 else if (strcmp (oo->name, "special") == 0)
1564 else if (strcmp (oo->name, "skip") == 0)
1566 else if (strcmp (oo->name, "default") == 0)
1568 else if (strcmp (oo->name, "descbits") == 0)
1570 else if (strcmp (oo->name, "param_is") == 0)
1572 else if (strncmp (oo->name, "param", 5) == 0
1573 && ISDIGIT (oo->name[5])
1574 && strcmp (oo->name + 6, "_is") == 0)
1576 else if (strcmp (oo->name, "chain_next") == 0)
1578 else if (strcmp (oo->name, "chain_prev") == 0)
1580 else if (strcmp (oo->name, "reorder") == 0)
1582 else
1583 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1585 if (d->used_length)
1586 length = NULL;
1588 if (use_params_p)
1590 int pointer_p = t->kind == TYPE_POINTER;
1592 if (pointer_p)
1593 t = t->u.p;
1594 if (! UNION_OR_STRUCT_P (t))
1595 error_at_line (d->line, "`use_params' option on unimplemented type");
1596 else
1597 t = find_param_structure (t, d->param);
1598 if (pointer_p)
1599 t = create_pointer (t);
1602 if (use_param_num != -1)
1604 if (d->param != NULL && d->param[use_param_num] != NULL)
1606 type_p nt = d->param[use_param_num];
1608 if (t->kind == TYPE_ARRAY)
1609 nt = create_array (nt, t->u.a.len);
1610 else if (length != NULL && t->kind == TYPE_POINTER)
1611 nt = create_pointer (nt);
1612 d->needs_cast_p = (t->kind != TYPE_POINTER
1613 && (nt->kind == TYPE_POINTER
1614 || nt->kind == TYPE_STRING));
1615 t = nt;
1617 else
1618 error_at_line (d->line, "no parameter defined for `%s'",
1619 d->val);
1622 if (maybe_undef_p
1623 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1625 error_at_line (d->line,
1626 "field `%s' has invalid option `maybe_undef_p'\n",
1627 d->val);
1628 return;
1631 switch (t->kind)
1633 case TYPE_SCALAR:
1634 case TYPE_STRING:
1635 d->process_field (t, d);
1636 break;
1638 case TYPE_POINTER:
1640 if (maybe_undef_p
1641 && t->u.p->u.s.line.file == NULL)
1643 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1644 break;
1647 if (! length)
1649 if (! UNION_OR_STRUCT_P (t->u.p)
1650 && t->u.p->kind != TYPE_PARAM_STRUCT)
1652 error_at_line (d->line,
1653 "field `%s' is pointer to unimplemented type",
1654 d->val);
1655 break;
1658 if (nested_ptr_d)
1660 const char *oldprevval2 = d->prev_val[2];
1662 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1664 error_at_line (d->line,
1665 "field `%s' has invalid "
1666 "option `nested_ptr'\n",
1667 d->val);
1668 return;
1671 d->prev_val[2] = d->val;
1672 oprintf (d->of, "%*s{\n", d->indent, "");
1673 d->indent += 2;
1674 d->val = xasprintf ("x%d", d->counter++);
1675 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1676 (nested_ptr_d->type->kind == TYPE_UNION
1677 ? "union" : "struct"),
1678 nested_ptr_d->type->u.s.tag,
1679 d->fn_wants_lvalue ? "" : "const ",
1680 d->val);
1681 oprintf (d->of, "%*s", d->indent + 2, "");
1682 output_escaped_param (d, nested_ptr_d->convert_from,
1683 "nested_ptr");
1684 oprintf (d->of, ";\n");
1686 d->process_field (nested_ptr_d->type, d);
1688 if (d->fn_wants_lvalue)
1690 oprintf (d->of, "%*s%s = ", d->indent, "",
1691 d->prev_val[2]);
1692 d->prev_val[2] = d->val;
1693 output_escaped_param (d, nested_ptr_d->convert_to,
1694 "nested_ptr");
1695 oprintf (d->of, ";\n");
1698 d->indent -= 2;
1699 oprintf (d->of, "%*s}\n", d->indent, "");
1700 d->val = d->prev_val[2];
1701 d->prev_val[2] = oldprevval2;
1703 else
1704 d->process_field (t->u.p, d);
1706 else
1708 int loopcounter = d->counter++;
1709 const char *oldval = d->val;
1710 const char *oldprevval3 = d->prev_val[3];
1711 char *newval;
1713 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1714 d->indent += 2;
1715 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1716 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1717 loopcounter, loopcounter);
1718 output_escaped_param (d, length, "length");
1719 oprintf (d->of, "); i%d++) {\n", loopcounter);
1720 d->indent += 2;
1721 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1722 d->used_length = 1;
1723 d->prev_val[3] = oldval;
1724 walk_type (t->u.p, d);
1725 free (newval);
1726 d->val = oldval;
1727 d->prev_val[3] = oldprevval3;
1728 d->used_length = 0;
1729 d->indent -= 2;
1730 oprintf (d->of, "%*s}\n", d->indent, "");
1731 d->process_field(t, d);
1732 d->indent -= 2;
1733 oprintf (d->of, "%*s}\n", d->indent, "");
1736 break;
1738 case TYPE_ARRAY:
1740 int loopcounter = d->counter++;
1741 const char *oldval = d->val;
1742 char *newval;
1744 /* If it's an array of scalars, we optimize by not generating
1745 any code. */
1746 if (t->u.a.p->kind == TYPE_SCALAR)
1747 break;
1749 oprintf (d->of, "%*s{\n", d->indent, "");
1750 d->indent += 2;
1751 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1752 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1753 loopcounter, loopcounter);
1754 if (length)
1755 output_escaped_param (d, length, "length");
1756 else
1757 oprintf (d->of, "%s", t->u.a.len);
1758 oprintf (d->of, "); i%d++) {\n", loopcounter);
1759 d->indent += 2;
1760 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1761 d->used_length = 1;
1762 walk_type (t->u.a.p, d);
1763 free (newval);
1764 d->used_length = 0;
1765 d->val = oldval;
1766 d->indent -= 2;
1767 oprintf (d->of, "%*s}\n", d->indent, "");
1768 d->indent -= 2;
1769 oprintf (d->of, "%*s}\n", d->indent, "");
1771 break;
1773 case TYPE_STRUCT:
1774 case TYPE_UNION:
1776 pair_p f;
1777 const char *oldval = d->val;
1778 const char *oldprevval1 = d->prev_val[1];
1779 const char *oldprevval2 = d->prev_val[2];
1780 const int union_p = t->kind == TYPE_UNION;
1781 int seen_default_p = 0;
1782 options_p o;
1784 if (! t->u.s.line.file)
1785 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1787 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1789 error_at_line (d->line,
1790 "structure `%s' defined for mismatching languages",
1791 t->u.s.tag);
1792 error_at_line (&t->u.s.line, "one structure defined here");
1795 /* Some things may also be defined in the structure's options. */
1796 for (o = t->u.s.opt; o; o = o->next)
1797 if (! desc && strcmp (o->name, "desc") == 0)
1798 desc = o->info;
1800 d->prev_val[2] = oldval;
1801 d->prev_val[1] = oldprevval2;
1802 if (union_p)
1804 if (desc == NULL)
1806 error_at_line (d->line, "missing `desc' option for union `%s'",
1807 t->u.s.tag);
1808 desc = "1";
1810 oprintf (d->of, "%*sswitch (", d->indent, "");
1811 output_escaped_param (d, desc, "desc");
1812 oprintf (d->of, ")\n");
1813 d->indent += 2;
1814 oprintf (d->of, "%*s{\n", d->indent, "");
1816 for (f = t->u.s.fields; f; f = f->next)
1818 options_p oo;
1819 const char *dot = ".";
1820 const char *tagid = NULL;
1821 int skip_p = 0;
1822 int default_p = 0;
1823 int use_param_p = 0;
1824 char *newval;
1826 d->reorder_fn = NULL;
1827 for (oo = f->opt; oo; oo = oo->next)
1828 if (strcmp (oo->name, "dot") == 0)
1829 dot = oo->info;
1830 else if (strcmp (oo->name, "tag") == 0)
1831 tagid = oo->info;
1832 else if (strcmp (oo->name, "skip") == 0)
1833 skip_p = 1;
1834 else if (strcmp (oo->name, "default") == 0)
1835 default_p = 1;
1836 else if (strcmp (oo->name, "reorder") == 0)
1837 d->reorder_fn = oo->info;
1838 else if (strncmp (oo->name, "use_param", 9) == 0
1839 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1840 use_param_p = 1;
1842 if (skip_p)
1843 continue;
1845 if (union_p && tagid)
1847 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1848 d->indent += 2;
1850 else if (union_p && default_p)
1852 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1853 d->indent += 2;
1854 seen_default_p = 1;
1856 else if (! union_p && (default_p || tagid))
1857 error_at_line (d->line,
1858 "can't use `%s' outside a union on field `%s'",
1859 default_p ? "default" : "tag", f->name);
1860 else if (union_p && ! (default_p || tagid)
1861 && f->type->kind == TYPE_SCALAR)
1863 fprintf (stderr,
1864 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1865 d->line->file, d->line->line, f->name);
1866 continue;
1868 else if (union_p && ! (default_p || tagid))
1869 error_at_line (d->line,
1870 "field `%s' is missing `tag' or `default' option",
1871 f->name);
1873 d->line = &f->line;
1874 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1875 d->opt = f->opt;
1876 d->used_length = false;
1878 if (union_p && use_param_p && d->param == NULL)
1879 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1880 else
1881 walk_type (f->type, d);
1883 free (newval);
1885 if (union_p)
1887 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1888 d->indent -= 2;
1891 d->reorder_fn = NULL;
1893 d->val = oldval;
1894 d->prev_val[1] = oldprevval1;
1895 d->prev_val[2] = oldprevval2;
1897 if (union_p && ! seen_default_p)
1899 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1900 oprintf (d->of, "%*s break;\n", d->indent, "");
1902 if (union_p)
1904 oprintf (d->of, "%*s}\n", d->indent, "");
1905 d->indent -= 2;
1908 break;
1910 case TYPE_LANG_STRUCT:
1912 type_p nt;
1913 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1914 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1915 break;
1916 if (nt == NULL)
1917 error_at_line (d->line, "structure `%s' differs between languages",
1918 t->u.s.tag);
1919 else
1920 walk_type (nt, d);
1922 break;
1924 case TYPE_PARAM_STRUCT:
1926 type_p *oldparam = d->param;
1928 d->param = t->u.param_struct.param;
1929 walk_type (t->u.param_struct.stru, d);
1930 d->param = oldparam;
1932 break;
1934 default:
1935 gcc_unreachable ();
1939 /* process_field routine for marking routines. */
1941 static void
1942 write_types_process_field (type_p f, const struct walk_type_data *d)
1944 const struct write_types_data *wtd;
1945 const char *cast = d->needs_cast_p ? "(void *)" : "";
1946 wtd = (const struct write_types_data *) d->cookie;
1948 switch (f->kind)
1950 case TYPE_POINTER:
1951 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1952 wtd->subfield_marker_routine, cast, d->val);
1953 if (wtd->param_prefix)
1955 oprintf (d->of, ", %s", d->prev_val[3]);
1956 if (d->orig_s)
1958 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1959 output_mangled_typename (d->of, d->orig_s);
1961 else
1962 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1964 if (f->u.p->kind == TYPE_PARAM_STRUCT
1965 && f->u.p->u.s.line.file != NULL)
1967 oprintf (d->of, ", gt_e_");
1968 output_mangled_typename (d->of, f);
1970 else if (UNION_OR_STRUCT_P (f)
1971 && f->u.p->u.s.line.file != NULL)
1973 oprintf (d->of, ", gt_ggc_e_");
1974 output_mangled_typename (d->of, f);
1976 else
1977 oprintf (d->of, ", gt_types_enum_last");
1979 oprintf (d->of, ");\n");
1980 if (d->reorder_fn && wtd->reorder_note_routine)
1981 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1982 wtd->reorder_note_routine, cast, d->val,
1983 d->prev_val[3], d->reorder_fn);
1984 break;
1986 case TYPE_STRING:
1987 if (wtd->param_prefix == NULL)
1988 break;
1990 case TYPE_STRUCT:
1991 case TYPE_UNION:
1992 case TYPE_LANG_STRUCT:
1993 case TYPE_PARAM_STRUCT:
1994 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1995 output_mangled_typename (d->of, f);
1996 oprintf (d->of, " (%s%s);\n", cast, d->val);
1997 if (d->reorder_fn && wtd->reorder_note_routine)
1998 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1999 wtd->reorder_note_routine, cast, d->val, cast, d->val,
2000 d->reorder_fn);
2001 break;
2003 case TYPE_SCALAR:
2004 break;
2006 default:
2007 gcc_unreachable ();
2011 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
2013 static void
2014 output_type_enum (outf_p of, type_p s)
2016 if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2018 oprintf (of, ", gt_e_");
2019 output_mangled_typename (of, s);
2021 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2023 oprintf (of, ", gt_ggc_e_");
2024 output_mangled_typename (of, s);
2026 else
2027 oprintf (of, ", gt_types_enum_last");
2030 /* For S, a structure that's part of ORIG_S, and using parameters
2031 PARAM, write out a routine that:
2032 - Takes a parameter, a void * but actually of type *S
2033 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2034 field of S or its substructures and (in some cases) things
2035 that are pointed to by S.
2038 static void
2039 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2040 const struct write_types_data *wtd)
2042 const char *fn = s->u.s.line.file;
2043 int i;
2044 const char *chain_next = NULL;
2045 const char *chain_prev = NULL;
2046 const char *mark_hook_name = NULL;
2047 options_p opt;
2048 struct walk_type_data d;
2050 /* This is a hack, and not the good kind either. */
2051 for (i = NUM_PARAM - 1; i >= 0; i--)
2052 if (param && param[i] && param[i]->kind == TYPE_POINTER
2053 && UNION_OR_STRUCT_P (param[i]->u.p))
2054 fn = param[i]->u.p->u.s.line.file;
2056 memset (&d, 0, sizeof (d));
2057 d.of = get_output_file_with_visibility (fn);
2059 for (opt = s->u.s.opt; opt; opt = opt->next)
2060 if (strcmp (opt->name, "chain_next") == 0)
2061 chain_next = opt->info;
2062 else if (strcmp (opt->name, "chain_prev") == 0)
2063 chain_prev = opt->info;
2064 else if (strcmp (opt->name, "mark_hook") == 0)
2065 mark_hook_name = opt->info;
2067 if (chain_prev != NULL && chain_next == NULL)
2068 error_at_line (&s->u.s.line, "chain_prev without chain_next");
2070 d.process_field = write_types_process_field;
2071 d.cookie = wtd;
2072 d.orig_s = orig_s;
2073 d.opt = s->u.s.opt;
2074 d.line = &s->u.s.line;
2075 d.bitmap = s->u.s.bitmap;
2076 d.param = param;
2077 d.prev_val[0] = "*x";
2078 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2079 d.prev_val[3] = "x";
2080 d.val = "(*x)";
2082 oprintf (d.of, "\n");
2083 oprintf (d.of, "void\n");
2084 if (param == NULL)
2085 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2086 else
2088 oprintf (d.of, "gt_%s_", wtd->prefix);
2089 output_mangled_typename (d.of, orig_s);
2091 oprintf (d.of, " (void *x_p)\n");
2092 oprintf (d.of, "{\n");
2093 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2094 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2095 chain_next == NULL ? "const " : "",
2096 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2097 if (chain_next != NULL)
2098 oprintf (d.of, " %s %s * xlimit = x;\n",
2099 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2100 if (chain_next == NULL)
2102 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2103 if (wtd->param_prefix)
2105 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2106 output_mangled_typename (d.of, orig_s);
2107 output_type_enum (d.of, orig_s);
2109 oprintf (d.of, "))\n");
2111 else
2113 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2114 if (wtd->param_prefix)
2116 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2117 output_mangled_typename (d.of, orig_s);
2118 output_type_enum (d.of, orig_s);
2120 oprintf (d.of, "))\n");
2121 if (mark_hook_name && !wtd->skip_hooks)
2123 oprintf (d.of, " {\n");
2124 oprintf (d.of, " %s (xlimit);\n ", mark_hook_name);
2126 oprintf (d.of, " xlimit = (");
2127 d.prev_val[2] = "*xlimit";
2128 output_escaped_param (&d, chain_next, "chain_next");
2129 oprintf (d.of, ");\n");
2130 if (mark_hook_name && !wtd->skip_hooks)
2131 oprintf (d.of, " }\n");
2132 if (chain_prev != NULL)
2134 oprintf (d.of, " if (x != xlimit)\n");
2135 oprintf (d.of, " for (;;)\n");
2136 oprintf (d.of, " {\n");
2137 oprintf (d.of, " %s %s * const xprev = (",
2138 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2140 d.prev_val[2] = "*x";
2141 output_escaped_param (&d, chain_prev, "chain_prev");
2142 oprintf (d.of, ");\n");
2143 oprintf (d.of, " if (xprev == NULL) break;\n");
2144 oprintf (d.of, " x = xprev;\n");
2145 oprintf (d.of, " (void) %s (xprev",
2146 wtd->marker_routine);
2147 if (wtd->param_prefix)
2149 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2150 output_mangled_typename (d.of, orig_s);
2151 output_type_enum (d.of, orig_s);
2153 oprintf (d.of, ");\n");
2154 oprintf (d.of, " }\n");
2156 oprintf (d.of, " while (x != xlimit)\n");
2158 oprintf (d.of, " {\n");
2159 if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2161 oprintf (d.of, " %s (x);\n", mark_hook_name);
2163 d.prev_val[2] = "*x";
2164 d.indent = 6;
2165 walk_type (s, &d);
2167 if (chain_next != NULL)
2169 oprintf (d.of, " x = (");
2170 output_escaped_param (&d, chain_next, "chain_next");
2171 oprintf (d.of, ");\n");
2174 oprintf (d.of, " }\n");
2175 oprintf (d.of, "}\n");
2178 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2180 static void
2181 write_types (type_p structures, type_p param_structs,
2182 const struct write_types_data *wtd)
2184 type_p s;
2186 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2187 for (s = structures; s; s = s->next)
2188 if (s->gc_used == GC_POINTED_TO
2189 || s->gc_used == GC_MAYBE_POINTED_TO)
2191 options_p opt;
2193 if (s->gc_used == GC_MAYBE_POINTED_TO
2194 && s->u.s.line.file == NULL)
2195 continue;
2197 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2198 output_mangled_typename (header_file, s);
2199 oprintf (header_file, "(X) do { \\\n");
2200 oprintf (header_file,
2201 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2202 s->u.s.tag);
2203 oprintf (header_file,
2204 " } while (0)\n");
2206 for (opt = s->u.s.opt; opt; opt = opt->next)
2207 if (strcmp (opt->name, "ptr_alias") == 0)
2209 type_p t = (type_p) opt->info;
2210 if (t->kind == TYPE_STRUCT
2211 || t->kind == TYPE_UNION
2212 || t->kind == TYPE_LANG_STRUCT)
2213 oprintf (header_file,
2214 "#define gt_%sx_%s gt_%sx_%s\n",
2215 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2216 else
2217 error_at_line (&s->u.s.line,
2218 "structure alias is not a structure");
2219 break;
2221 if (opt)
2222 continue;
2224 /* Declare the marker procedure only once. */
2225 oprintf (header_file,
2226 "extern void gt_%sx_%s (void *);\n",
2227 wtd->prefix, s->u.s.tag);
2229 if (s->u.s.line.file == NULL)
2231 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2232 s->u.s.tag);
2233 continue;
2236 if (s->kind == TYPE_LANG_STRUCT)
2238 type_p ss;
2239 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2240 write_func_for_structure (s, ss, NULL, wtd);
2242 else
2243 write_func_for_structure (s, s, NULL, wtd);
2246 for (s = param_structs; s; s = s->next)
2247 if (s->gc_used == GC_POINTED_TO)
2249 type_p * param = s->u.param_struct.param;
2250 type_p stru = s->u.param_struct.stru;
2252 /* Declare the marker procedure. */
2253 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2254 output_mangled_typename (header_file, s);
2255 oprintf (header_file, " (void *);\n");
2257 if (stru->u.s.line.file == NULL)
2259 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2260 s->u.s.tag);
2261 continue;
2264 if (stru->kind == TYPE_LANG_STRUCT)
2266 type_p ss;
2267 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2268 write_func_for_structure (s, ss, param, wtd);
2270 else
2271 write_func_for_structure (s, stru, param, wtd);
2275 static const struct write_types_data ggc_wtd =
2277 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2278 "GC marker procedures. ",
2279 FALSE
2282 static const struct write_types_data pch_wtd =
2284 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2285 "gt_pch_note_reorder",
2286 "PCH type-walking procedures. ",
2287 TRUE
2290 /* Write out the local pointer-walking routines. */
2292 /* process_field routine for local pointer-walking. */
2294 static void
2295 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2297 switch (f->kind)
2299 case TYPE_POINTER:
2300 case TYPE_STRUCT:
2301 case TYPE_UNION:
2302 case TYPE_LANG_STRUCT:
2303 case TYPE_PARAM_STRUCT:
2304 case TYPE_STRING:
2305 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2306 d->prev_val[3]);
2307 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2308 break;
2310 case TYPE_SCALAR:
2311 break;
2313 default:
2314 gcc_unreachable ();
2318 /* For S, a structure that's part of ORIG_S, and using parameters
2319 PARAM, write out a routine that:
2320 - Is of type gt_note_pointers
2321 - Calls PROCESS_FIELD on each field of S or its substructures.
2324 static void
2325 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2327 const char *fn = s->u.s.line.file;
2328 int i;
2329 struct walk_type_data d;
2331 /* This is a hack, and not the good kind either. */
2332 for (i = NUM_PARAM - 1; i >= 0; i--)
2333 if (param && param[i] && param[i]->kind == TYPE_POINTER
2334 && UNION_OR_STRUCT_P (param[i]->u.p))
2335 fn = param[i]->u.p->u.s.line.file;
2337 memset (&d, 0, sizeof (d));
2338 d.of = get_output_file_with_visibility (fn);
2340 d.process_field = write_types_local_process_field;
2341 d.opt = s->u.s.opt;
2342 d.line = &s->u.s.line;
2343 d.bitmap = s->u.s.bitmap;
2344 d.param = param;
2345 d.prev_val[0] = d.prev_val[2] = "*x";
2346 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2347 d.prev_val[3] = "x";
2348 d.val = "(*x)";
2349 d.fn_wants_lvalue = true;
2351 oprintf (d.of, "\n");
2352 oprintf (d.of, "void\n");
2353 oprintf (d.of, "gt_pch_p_");
2354 output_mangled_typename (d.of, orig_s);
2355 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2356 "\tvoid *x_p,\n"
2357 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2358 "\tATTRIBUTE_UNUSED void *cookie)\n");
2359 oprintf (d.of, "{\n");
2360 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2361 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2362 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2363 d.indent = 2;
2364 walk_type (s, &d);
2365 oprintf (d.of, "}\n");
2368 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2370 static void
2371 write_local (type_p structures, type_p param_structs)
2373 type_p s;
2375 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2376 for (s = structures; s; s = s->next)
2377 if (s->gc_used == GC_POINTED_TO
2378 || s->gc_used == GC_MAYBE_POINTED_TO)
2380 options_p opt;
2382 if (s->u.s.line.file == NULL)
2383 continue;
2385 for (opt = s->u.s.opt; opt; opt = opt->next)
2386 if (strcmp (opt->name, "ptr_alias") == 0)
2388 type_p t = (type_p) opt->info;
2389 if (t->kind == TYPE_STRUCT
2390 || t->kind == TYPE_UNION
2391 || t->kind == TYPE_LANG_STRUCT)
2393 oprintf (header_file, "#define gt_pch_p_");
2394 output_mangled_typename (header_file, s);
2395 oprintf (header_file, " gt_pch_p_");
2396 output_mangled_typename (header_file, t);
2397 oprintf (header_file, "\n");
2399 else
2400 error_at_line (&s->u.s.line,
2401 "structure alias is not a structure");
2402 break;
2404 if (opt)
2405 continue;
2407 /* Declare the marker procedure only once. */
2408 oprintf (header_file, "extern void gt_pch_p_");
2409 output_mangled_typename (header_file, s);
2410 oprintf (header_file,
2411 "\n (void *, void *, gt_pointer_operator, void *);\n");
2413 if (s->kind == TYPE_LANG_STRUCT)
2415 type_p ss;
2416 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2417 write_local_func_for_structure (s, ss, NULL);
2419 else
2420 write_local_func_for_structure (s, s, NULL);
2423 for (s = param_structs; s; s = s->next)
2424 if (s->gc_used == GC_POINTED_TO)
2426 type_p * param = s->u.param_struct.param;
2427 type_p stru = s->u.param_struct.stru;
2429 /* Declare the marker procedure. */
2430 oprintf (header_file, "extern void gt_pch_p_");
2431 output_mangled_typename (header_file, s);
2432 oprintf (header_file,
2433 "\n (void *, void *, gt_pointer_operator, void *);\n");
2435 if (stru->u.s.line.file == NULL)
2437 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2438 s->u.s.tag);
2439 continue;
2442 if (stru->kind == TYPE_LANG_STRUCT)
2444 type_p ss;
2445 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2446 write_local_func_for_structure (s, ss, param);
2448 else
2449 write_local_func_for_structure (s, stru, param);
2453 /* Write out the 'enum' definition for gt_types_enum. */
2455 static void
2456 write_enum_defn (type_p structures, type_p param_structs)
2458 type_p s;
2460 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2461 oprintf (header_file, "enum gt_types_enum {\n");
2462 for (s = structures; s; s = s->next)
2463 if (s->gc_used == GC_POINTED_TO
2464 || s->gc_used == GC_MAYBE_POINTED_TO)
2466 if (s->gc_used == GC_MAYBE_POINTED_TO
2467 && s->u.s.line.file == NULL)
2468 continue;
2470 oprintf (header_file, " gt_ggc_e_");
2471 output_mangled_typename (header_file, s);
2472 oprintf (header_file, ", \n");
2474 for (s = param_structs; s; s = s->next)
2475 if (s->gc_used == GC_POINTED_TO)
2477 oprintf (header_file, " gt_e_");
2478 output_mangled_typename (header_file, s);
2479 oprintf (header_file, ", \n");
2481 oprintf (header_file, " gt_types_enum_last\n");
2482 oprintf (header_file, "};\n");
2485 /* Might T contain any non-pointer elements? */
2487 static int
2488 contains_scalar_p (type_p t)
2490 switch (t->kind)
2492 case TYPE_STRING:
2493 case TYPE_POINTER:
2494 return 0;
2495 case TYPE_ARRAY:
2496 return contains_scalar_p (t->u.a.p);
2497 default:
2498 /* Could also check for structures that have no non-pointer
2499 fields, but there aren't enough of those to worry about. */
2500 return 1;
2504 /* Mangle FN and print it to F. */
2506 static void
2507 put_mangled_filename (outf_p f, const char *fn)
2509 const char *name = get_output_file_name (fn);
2510 for (; *name != 0; name++)
2511 if (ISALNUM (*name))
2512 oprintf (f, "%c", *name);
2513 else
2514 oprintf (f, "%c", '_');
2517 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2518 LASTNAME, and NAME are all strings to insert in various places in
2519 the resulting code. */
2521 static void
2522 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2523 const char *tname, const char *name)
2525 struct flist *fli2;
2527 for (fli2 = flp; fli2; fli2 = fli2->next)
2528 if (fli2->started_p)
2530 oprintf (fli2->f, " %s\n", lastname);
2531 oprintf (fli2->f, "};\n\n");
2534 for (fli2 = flp; fli2; fli2 = fli2->next)
2535 if (fli2->started_p)
2537 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2538 int fnum;
2540 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2541 if (bitmap & 1)
2543 oprintf (base_files[fnum],
2544 "extern const struct %s gt_%s_",
2545 tname, pfx);
2546 put_mangled_filename (base_files[fnum], fli2->name);
2547 oprintf (base_files[fnum], "[];\n");
2552 size_t fnum;
2553 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2554 oprintf (base_files [fnum],
2555 "const struct %s * const %s[] = {\n",
2556 tname, name);
2560 for (fli2 = flp; fli2; fli2 = fli2->next)
2561 if (fli2->started_p)
2563 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2564 int fnum;
2566 fli2->started_p = 0;
2568 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2569 if (bitmap & 1)
2571 oprintf (base_files[fnum], " gt_%s_", pfx);
2572 put_mangled_filename (base_files[fnum], fli2->name);
2573 oprintf (base_files[fnum], ",\n");
2578 size_t fnum;
2579 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2581 oprintf (base_files[fnum], " NULL\n");
2582 oprintf (base_files[fnum], "};\n");
2587 /* Write out to F the table entry and any marker routines needed to
2588 mark NAME as TYPE. The original variable is V, at LINE.
2589 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2590 is nonzero iff we are building the root table for hash table caches. */
2592 static void
2593 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2594 struct fileloc *line, const char *if_marked)
2596 switch (type->kind)
2598 case TYPE_STRUCT:
2600 pair_p fld;
2601 for (fld = type->u.s.fields; fld; fld = fld->next)
2603 int skip_p = 0;
2604 const char *desc = NULL;
2605 options_p o;
2607 for (o = fld->opt; o; o = o->next)
2608 if (strcmp (o->name, "skip") == 0)
2609 skip_p = 1;
2610 else if (strcmp (o->name, "desc") == 0)
2611 desc = o->info;
2612 else
2613 error_at_line (line,
2614 "field `%s' of global `%s' has unknown option `%s'",
2615 fld->name, name, o->name);
2617 if (skip_p)
2618 continue;
2619 else if (desc && fld->type->kind == TYPE_UNION)
2621 pair_p validf = NULL;
2622 pair_p ufld;
2624 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2626 const char *tag = NULL;
2627 options_p oo;
2629 for (oo = ufld->opt; oo; oo = oo->next)
2630 if (strcmp (oo->name, "tag") == 0)
2631 tag = oo->info;
2632 if (tag == NULL || strcmp (tag, desc) != 0)
2633 continue;
2634 if (validf != NULL)
2635 error_at_line (line,
2636 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2637 name, fld->name, validf->name,
2638 name, fld->name, ufld->name,
2639 tag);
2640 validf = ufld;
2642 if (validf != NULL)
2644 char *newname;
2645 newname = xasprintf ("%s.%s.%s",
2646 name, fld->name, validf->name);
2647 write_root (f, v, validf->type, newname, 0, line,
2648 if_marked);
2649 free (newname);
2652 else if (desc)
2653 error_at_line (line,
2654 "global `%s.%s' has `desc' option but is not union",
2655 name, fld->name);
2656 else
2658 char *newname;
2659 newname = xasprintf ("%s.%s", name, fld->name);
2660 write_root (f, v, fld->type, newname, 0, line, if_marked);
2661 free (newname);
2665 break;
2667 case TYPE_ARRAY:
2669 char *newname;
2670 newname = xasprintf ("%s[0]", name);
2671 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2672 free (newname);
2674 break;
2676 case TYPE_POINTER:
2678 type_p ap, tp;
2680 oprintf (f, " {\n");
2681 oprintf (f, " &%s,\n", name);
2682 oprintf (f, " 1");
2684 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2685 if (ap->u.a.len[0])
2686 oprintf (f, " * (%s)", ap->u.a.len);
2687 else if (ap == v->type)
2688 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2689 oprintf (f, ",\n");
2690 oprintf (f, " sizeof (%s", v->name);
2691 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2692 oprintf (f, "[0]");
2693 oprintf (f, "),\n");
2695 tp = type->u.p;
2697 if (! has_length && UNION_OR_STRUCT_P (tp))
2699 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2700 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2702 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2704 oprintf (f, " &gt_ggc_m_");
2705 output_mangled_typename (f, tp);
2706 oprintf (f, ",\n &gt_pch_n_");
2707 output_mangled_typename (f, tp);
2709 else if (has_length
2710 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2712 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2713 oprintf (f, " &gt_pch_na_%s", name);
2715 else
2717 error_at_line (line,
2718 "global `%s' is pointer to unimplemented type",
2719 name);
2721 if (if_marked)
2722 oprintf (f, ",\n &%s", if_marked);
2723 oprintf (f, "\n },\n");
2725 break;
2727 case TYPE_STRING:
2729 oprintf (f, " {\n");
2730 oprintf (f, " &%s,\n", name);
2731 oprintf (f, " 1, \n");
2732 oprintf (f, " sizeof (%s),\n", v->name);
2733 oprintf (f, " &gt_ggc_m_S,\n");
2734 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2735 oprintf (f, " },\n");
2737 break;
2739 case TYPE_SCALAR:
2740 break;
2742 default:
2743 error_at_line (line,
2744 "global `%s' is unimplemented type",
2745 name);
2749 /* This generates a routine to walk an array. */
2751 static void
2752 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2754 struct walk_type_data d;
2755 char *prevval3;
2757 memset (&d, 0, sizeof (d));
2758 d.of = f;
2759 d.cookie = wtd;
2760 d.indent = 2;
2761 d.line = &v->line;
2762 d.opt = v->opt;
2763 d.bitmap = get_base_file_bitmap (v->line.file);
2764 d.param = NULL;
2766 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2768 if (wtd->param_prefix)
2770 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2771 oprintf (f,
2772 " (void *, void *, gt_pointer_operator, void *);\n");
2773 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2774 wtd->param_prefix, v->name);
2775 oprintf (d.of,
2776 " ATTRIBUTE_UNUSED void *x_p,\n"
2777 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2778 " ATTRIBUTE_UNUSED void * cookie)\n");
2779 oprintf (d.of, "{\n");
2780 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2781 d.process_field = write_types_local_process_field;
2782 walk_type (v->type, &d);
2783 oprintf (f, "}\n\n");
2786 d.opt = v->opt;
2787 oprintf (f, "static void gt_%sa_%s (void *);\n",
2788 wtd->prefix, v->name);
2789 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2790 wtd->prefix, v->name);
2791 oprintf (f, "{\n");
2792 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2793 d.process_field = write_types_process_field;
2794 walk_type (v->type, &d);
2795 free (prevval3);
2796 oprintf (f, "}\n\n");
2799 /* Output a table describing the locations and types of VARIABLES. */
2801 static void
2802 write_roots (pair_p variables)
2804 pair_p v;
2805 struct flist *flp = NULL;
2807 for (v = variables; v; v = v->next)
2809 outf_p f = get_output_file_with_visibility (v->line.file);
2810 struct flist *fli;
2811 const char *length = NULL;
2812 int deletable_p = 0;
2813 options_p o;
2815 for (o = v->opt; o; o = o->next)
2816 if (strcmp (o->name, "length") == 0)
2817 length = o->info;
2818 else if (strcmp (o->name, "deletable") == 0)
2819 deletable_p = 1;
2820 else if (strcmp (o->name, "param_is") == 0)
2822 else if (strncmp (o->name, "param", 5) == 0
2823 && ISDIGIT (o->name[5])
2824 && strcmp (o->name + 6, "_is") == 0)
2826 else if (strcmp (o->name, "if_marked") == 0)
2828 else
2829 error_at_line (&v->line,
2830 "global `%s' has unknown option `%s'",
2831 v->name, o->name);
2833 for (fli = flp; fli; fli = fli->next)
2834 if (fli->f == f)
2835 break;
2836 if (fli == NULL)
2838 fli = XNEW (struct flist);
2839 fli->f = f;
2840 fli->next = flp;
2841 fli->started_p = 0;
2842 fli->name = v->line.file;
2843 flp = fli;
2845 oprintf (f, "\n/* GC roots. */\n\n");
2848 if (! deletable_p
2849 && length
2850 && v->type->kind == TYPE_POINTER
2851 && (v->type->u.p->kind == TYPE_POINTER
2852 || v->type->u.p->kind == TYPE_STRUCT))
2854 write_array (f, v, &ggc_wtd);
2855 write_array (f, v, &pch_wtd);
2859 for (v = variables; v; v = v->next)
2861 outf_p f = get_output_file_with_visibility (v->line.file);
2862 struct flist *fli;
2863 int skip_p = 0;
2864 int length_p = 0;
2865 options_p o;
2867 for (o = v->opt; o; o = o->next)
2868 if (strcmp (o->name, "length") == 0)
2869 length_p = 1;
2870 else if (strcmp (o->name, "deletable") == 0
2871 || strcmp (o->name, "if_marked") == 0)
2872 skip_p = 1;
2874 if (skip_p)
2875 continue;
2877 for (fli = flp; fli; fli = fli->next)
2878 if (fli->f == f)
2879 break;
2880 if (! fli->started_p)
2882 fli->started_p = 1;
2884 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2885 put_mangled_filename (f, v->line.file);
2886 oprintf (f, "[] = {\n");
2889 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2892 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2893 "gt_ggc_rtab");
2895 for (v = variables; v; v = v->next)
2897 outf_p f = get_output_file_with_visibility (v->line.file);
2898 struct flist *fli;
2899 int skip_p = 1;
2900 options_p o;
2902 for (o = v->opt; o; o = o->next)
2903 if (strcmp (o->name, "deletable") == 0)
2904 skip_p = 0;
2905 else if (strcmp (o->name, "if_marked") == 0)
2906 skip_p = 1;
2908 if (skip_p)
2909 continue;
2911 for (fli = flp; fli; fli = fli->next)
2912 if (fli->f == f)
2913 break;
2914 if (! fli->started_p)
2916 fli->started_p = 1;
2918 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2919 put_mangled_filename (f, v->line.file);
2920 oprintf (f, "[] = {\n");
2923 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2924 v->name, v->name);
2927 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2928 "gt_ggc_deletable_rtab");
2930 for (v = variables; v; v = v->next)
2932 outf_p f = get_output_file_with_visibility (v->line.file);
2933 struct flist *fli;
2934 const char *if_marked = NULL;
2935 int length_p = 0;
2936 options_p o;
2938 for (o = v->opt; o; o = o->next)
2939 if (strcmp (o->name, "length") == 0)
2940 length_p = 1;
2941 else if (strcmp (o->name, "if_marked") == 0)
2942 if_marked = o->info;
2944 if (if_marked == NULL)
2945 continue;
2947 if (v->type->kind != TYPE_POINTER
2948 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2949 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2951 error_at_line (&v->line, "if_marked option used but not hash table");
2952 continue;
2955 for (fli = flp; fli; fli = fli->next)
2956 if (fli->f == f)
2957 break;
2958 if (! fli->started_p)
2960 fli->started_p = 1;
2962 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2963 put_mangled_filename (f, v->line.file);
2964 oprintf (f, "[] = {\n");
2967 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2968 v->name, length_p, &v->line, if_marked);
2971 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2972 "gt_ggc_cache_rtab");
2974 for (v = variables; v; v = v->next)
2976 outf_p f = get_output_file_with_visibility (v->line.file);
2977 struct flist *fli;
2978 int length_p = 0;
2979 int if_marked_p = 0;
2980 options_p o;
2982 for (o = v->opt; o; o = o->next)
2983 if (strcmp (o->name, "length") == 0)
2984 length_p = 1;
2985 else if (strcmp (o->name, "if_marked") == 0)
2986 if_marked_p = 1;
2988 if (! if_marked_p)
2989 continue;
2991 for (fli = flp; fli; fli = fli->next)
2992 if (fli->f == f)
2993 break;
2994 if (! fli->started_p)
2996 fli->started_p = 1;
2998 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2999 put_mangled_filename (f, v->line.file);
3000 oprintf (f, "[] = {\n");
3003 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3006 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3007 "gt_pch_cache_rtab");
3009 for (v = variables; v; v = v->next)
3011 outf_p f = get_output_file_with_visibility (v->line.file);
3012 struct flist *fli;
3013 int skip_p = 0;
3014 options_p o;
3016 for (o = v->opt; o; o = o->next)
3017 if (strcmp (o->name, "deletable") == 0
3018 || strcmp (o->name, "if_marked") == 0)
3019 skip_p = 1;
3021 if (skip_p)
3022 continue;
3024 if (! contains_scalar_p (v->type))
3025 continue;
3027 for (fli = flp; fli; fli = fli->next)
3028 if (fli->f == f)
3029 break;
3030 if (! fli->started_p)
3032 fli->started_p = 1;
3034 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3035 put_mangled_filename (f, v->line.file);
3036 oprintf (f, "[] = {\n");
3039 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3040 v->name, v->name);
3043 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3044 "gt_pch_scalar_rtab");
3048 extern int main (int argc, char **argv);
3050 main (int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
3052 unsigned i;
3053 static struct fileloc pos = { __FILE__, __LINE__ };
3054 unsigned j;
3056 gen_rtx_next ();
3058 srcdir_len = strlen (srcdir);
3060 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3061 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3062 do_scalar_typedef ("double_int", &pos);
3063 do_scalar_typedef ("uint8", &pos);
3064 do_scalar_typedef ("jword", &pos);
3065 do_scalar_typedef ("JCF_u2", &pos);
3066 #ifdef USE_MAPPED_LOCATION
3067 do_scalar_typedef ("location_t", &pos);
3068 do_scalar_typedef ("source_locus", &pos);
3069 #endif
3070 do_scalar_typedef ("void", &pos);
3072 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3074 do_typedef ("HARD_REG_SET", create_array (
3075 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3076 "2"), &pos);
3078 for (i = 0; i < NUM_GT_FILES; i++)
3080 int dupflag = 0;
3081 /* Omit if already seen. */
3082 for (j = 0; j < i; j++)
3084 if (!strcmp (all_files[i], all_files[j]))
3086 dupflag = 1;
3087 break;
3090 if (!dupflag)
3091 parse_file (all_files[i]);
3092 #ifndef USE_MAPPED_LOCATION
3093 /* temporary kludge - gengtype doesn't handle conditionals.
3094 Manually add source_locus *after* we've processed input.h. */
3095 if (i == 0)
3096 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3097 #endif
3100 if (hit_error != 0)
3101 exit (1);
3103 set_gc_used (variables);
3105 open_base_files ();
3106 write_enum_defn (structures, param_structs);
3107 write_types (structures, param_structs, &ggc_wtd);
3108 write_types (structures, param_structs, &pch_wtd);
3109 write_local (structures, param_structs);
3110 write_roots (variables);
3111 write_rtx_next ();
3112 close_output_files ();
3114 return (hit_error != 0);