2004-08-18 David Daney <ddaney@avtrex.com>
[official-gcc.git] / gcc / gengtype.c
blob6cb89f0e8725a5f4f8b8edaf5e9c62349859e555
1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004 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, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, 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 "rtl.h"
28 #undef abort
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 a new structure with tag NAME (or a union iff ISUNION is nonzero),
148 at POS with fields FIELDS and options O. */
150 void
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;
220 /* Return the previously-defined structure with tag NAME (or a union
221 iff ISUNION is nonzero), or a new empty structure or union if none
222 was defined previously. */
224 type_p
225 find_structure (const char *name, int isunion)
227 type_p s;
229 for (s = structures; s != NULL; s = s->next)
230 if (strcmp (name, s->u.s.tag) == 0
231 && UNION_P (s) == isunion)
232 return s;
234 s = XCNEW (struct type);
235 s->next = structures;
236 structures = s;
237 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
238 s->u.s.tag = name;
239 structures = s;
240 return s;
243 /* Return the previously-defined parameterized structure for structure
244 T and parameters PARAM, or a new parameterized empty structure or
245 union if none was defined previously. */
247 static type_p
248 find_param_structure (type_p t, type_p param[NUM_PARAM])
250 type_p res;
252 for (res = param_structs; res; res = res->next)
253 if (res->u.param_struct.stru == t
254 && memcmp (res->u.param_struct.param, param,
255 sizeof (type_p) * NUM_PARAM) == 0)
256 break;
257 if (res == NULL)
259 res = XCNEW (struct type);
260 res->kind = TYPE_PARAM_STRUCT;
261 res->next = param_structs;
262 param_structs = res;
263 res->u.param_struct.stru = t;
264 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
266 return res;
269 /* Return a scalar type with name NAME. */
271 type_p
272 create_scalar_type (const char *name, size_t name_len)
274 type_p r = XCNEW (struct type);
275 r->kind = TYPE_SCALAR;
276 r->u.sc = (char *) xmemdup (name, name_len, name_len + 1);
277 return r;
280 /* Return a pointer to T. */
282 type_p
283 create_pointer (type_p t)
285 if (! t->pointer_to)
287 type_p r = XCNEW (struct type);
288 r->kind = TYPE_POINTER;
289 r->u.p = t;
290 t->pointer_to = r;
292 return t->pointer_to;
295 /* Return an array of length LEN. */
297 type_p
298 create_array (type_p t, const char *len)
300 type_p v;
302 v = XCNEW (struct type);
303 v->kind = TYPE_ARRAY;
304 v->u.a.p = t;
305 v->u.a.len = len;
306 return v;
309 /* Return an options structure with name NAME and info INFO. */
310 options_p
311 create_option (const char *name, void *info)
313 options_p o = XNEW (struct options);
314 o->name = name;
315 o->info = (const char*) info;
316 return o;
319 /* Add a variable named S of type T with options O defined at POS,
320 to `variables'. */
322 void
323 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
325 pair_p n;
326 n = XNEW (struct pair);
327 n->name = s;
328 n->type = t;
329 n->line = *pos;
330 n->opt = o;
331 n->next = variables;
332 variables = n;
335 /* We really don't care how long a CONST_DOUBLE is. */
336 #define CONST_DOUBLE_FORMAT "ww"
337 const char * const rtx_format[NUM_RTX_CODE] = {
338 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
339 #include "rtl.def"
340 #undef DEF_RTL_EXPR
343 static int rtx_next_new[NUM_RTX_CODE];
345 /* Generate the contents of the rtx_next array. This really doesn't belong
346 in gengtype at all, but it's needed for adjust_field_rtx_def. */
348 static void
349 gen_rtx_next (void)
351 int i;
352 for (i = 0; i < NUM_RTX_CODE; i++)
354 int k;
356 rtx_next_new[i] = -1;
357 if (strncmp (rtx_format[i], "iuu", 3) == 0)
358 rtx_next_new[i] = 2;
359 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
360 rtx_next_new[i] = 1;
361 else
362 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
363 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
364 rtx_next_new[i] = k;
368 /* Write out the contents of the rtx_next array. */
369 static void
370 write_rtx_next (void)
372 outf_p f = get_output_file_with_visibility (NULL);
373 int i;
375 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
376 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
377 for (i = 0; i < NUM_RTX_CODE; i++)
378 if (rtx_next_new[i] == -1)
379 oprintf (f, " 0,\n");
380 else
381 oprintf (f,
382 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
383 rtx_next_new[i]);
384 oprintf (f, "};\n");
387 /* Handle `special("rtx_def")'. This is a special case for field
388 `fld' of struct rtx_def, which is an array of unions whose values
389 are based in a complex way on the type of RTL. */
391 static type_p
392 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
394 pair_p flds = NULL;
395 options_p nodot;
396 int i;
397 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
398 type_p bitmap_tp, basic_block_tp, reg_attrs_tp;
400 static const char * const rtx_name[NUM_RTX_CODE] = {
401 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
402 #include "rtl.def"
403 #undef DEF_RTL_EXPR
406 if (t->kind != TYPE_UNION)
408 error_at_line (&lexer_line,
409 "special `rtx_def' must be applied to a union");
410 return &string_type;
413 nodot = XNEW (struct options);
414 nodot->next = NULL;
415 nodot->name = "dot";
416 nodot->info = "";
418 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
419 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
420 tree_tp = create_pointer (find_structure ("tree_node", 1));
421 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
422 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
423 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
424 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
425 scalar_tp = create_scalar_type ("rtunion scalar", 14);
428 pair_p note_flds = NULL;
429 int c;
431 for (c = NOTE_INSN_BIAS; c <= NOTE_INSN_MAX; c++)
433 pair_p old_note_flds = note_flds;
435 note_flds = XNEW (struct pair);
436 note_flds->line.file = __FILE__;
437 note_flds->line.line = __LINE__;
438 note_flds->opt = XNEW (struct options);
439 note_flds->opt->next = nodot;
440 note_flds->opt->name = "tag";
441 note_flds->opt->info = xasprintf ("%d", c);
442 note_flds->next = old_note_flds;
444 switch (c)
446 /* NOTE_INSN_MAX is used as the default field for line
447 number notes. */
448 case NOTE_INSN_MAX:
449 note_flds->opt->name = "default";
450 note_flds->name = "rt_str";
451 note_flds->type = &string_type;
452 break;
454 case NOTE_INSN_BLOCK_BEG:
455 case NOTE_INSN_BLOCK_END:
456 note_flds->name = "rt_tree";
457 note_flds->type = tree_tp;
458 break;
460 case NOTE_INSN_EXPECTED_VALUE:
461 case NOTE_INSN_VAR_LOCATION:
462 note_flds->name = "rt_rtx";
463 note_flds->type = rtx_tp;
464 break;
466 default:
467 note_flds->name = "rt_int";
468 note_flds->type = scalar_tp;
469 break;
472 new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL);
475 note_union_tp = find_structure ("rtx_def_note_subunion", 1);
477 for (i = 0; i < NUM_RTX_CODE; i++)
479 pair_p old_flds = flds;
480 pair_p subfields = NULL;
481 size_t aindex, nmindex;
482 const char *sname;
483 char *ftag;
485 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
487 pair_p old_subf = subfields;
488 type_p t;
489 const char *subname;
491 switch (rtx_format[i][aindex])
493 case '*':
494 case 'i':
495 case 'n':
496 case 'w':
497 t = scalar_tp;
498 subname = "rt_int";
499 break;
501 case '0':
502 if (i == MEM && aindex == 1)
503 t = mem_attrs_tp, subname = "rt_mem";
504 else if (i == JUMP_INSN && aindex == 9)
505 t = rtx_tp, subname = "rt_rtx";
506 else if (i == CODE_LABEL && aindex == 4)
507 t = scalar_tp, subname = "rt_int";
508 else if (i == CODE_LABEL && aindex == 5)
509 t = rtx_tp, subname = "rt_rtx";
510 else if (i == LABEL_REF
511 && (aindex == 1 || aindex == 2))
512 t = rtx_tp, subname = "rt_rtx";
513 else if (i == NOTE && aindex == 4)
514 t = note_union_tp, subname = "";
515 else if (i == NOTE && aindex >= 7)
516 t = scalar_tp, subname = "rt_int";
517 else if (i == ADDR_DIFF_VEC && aindex == 4)
518 t = scalar_tp, subname = "rt_int";
519 else if (i == VALUE && aindex == 0)
520 t = scalar_tp, subname = "rt_int";
521 else if (i == REG && aindex == 1)
522 t = scalar_tp, subname = "rt_int";
523 else if (i == REG && aindex == 2)
524 t = reg_attrs_tp, subname = "rt_reg";
525 else if (i == SCRATCH && aindex == 0)
526 t = scalar_tp, subname = "rt_int";
527 else if (i == SYMBOL_REF && aindex == 1)
528 t = scalar_tp, subname = "rt_int";
529 else if (i == SYMBOL_REF && aindex == 2)
530 t = tree_tp, subname = "rt_tree";
531 else if (i == BARRIER && aindex >= 3)
532 t = scalar_tp, subname = "rt_int";
533 else
535 error_at_line (&lexer_line,
536 "rtx type `%s' has `0' in position %lu, can't handle",
537 rtx_name[i], (unsigned long) aindex);
538 t = &string_type;
539 subname = "rt_int";
541 break;
543 case 's':
544 case 'S':
545 case 'T':
546 t = &string_type;
547 subname = "rt_str";
548 break;
550 case 'e':
551 case 'u':
552 t = rtx_tp;
553 subname = "rt_rtx";
554 break;
556 case 'E':
557 case 'V':
558 t = rtvec_tp;
559 subname = "rt_rtvec";
560 break;
562 case 't':
563 t = tree_tp;
564 subname = "rt_tree";
565 break;
567 case 'b':
568 t = bitmap_tp;
569 subname = "rt_bit";
570 break;
572 case 'B':
573 t = basic_block_tp;
574 subname = "rt_bb";
575 break;
577 default:
578 error_at_line (&lexer_line,
579 "rtx type `%s' has `%c' in position %lu, can't handle",
580 rtx_name[i], rtx_format[i][aindex],
581 (unsigned long)aindex);
582 t = &string_type;
583 subname = "rt_int";
584 break;
587 subfields = XNEW (struct pair);
588 subfields->next = old_subf;
589 subfields->type = t;
590 subfields->name = xasprintf (".fld[%lu].%s", (unsigned long)aindex,
591 subname);
592 subfields->line.file = __FILE__;
593 subfields->line.line = __LINE__;
594 if (t == note_union_tp)
596 subfields->opt = XNEW (struct options);
597 subfields->opt->next = nodot;
598 subfields->opt->name = "desc";
599 subfields->opt->info = "NOTE_LINE_NUMBER (&%0)";
601 else if (t == basic_block_tp)
603 /* We don't presently GC basic block structures... */
604 subfields->opt = XNEW (struct options);
605 subfields->opt->next = nodot;
606 subfields->opt->name = "skip";
607 subfields->opt->info = NULL;
609 else
610 subfields->opt = nodot;
613 flds = XNEW (struct pair);
614 flds->next = old_flds;
615 flds->name = "";
616 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
617 new_structure (sname, 0, &lexer_line, subfields, NULL);
618 flds->type = find_structure (sname, 0);
619 flds->line.file = __FILE__;
620 flds->line.line = __LINE__;
621 flds->opt = XNEW (struct options);
622 flds->opt->next = nodot;
623 flds->opt->name = "tag";
624 ftag = xstrdup (rtx_name[i]);
625 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
626 ftag[nmindex] = TOUPPER (ftag[nmindex]);
627 flds->opt->info = ftag;
630 new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
631 return find_structure ("rtx_def_subunion", 1);
634 /* Handle `special("tree_exp")'. This is a special case for
635 field `operands' of struct tree_exp, which although it claims to contain
636 pointers to trees, actually sometimes contains pointers to RTL too.
637 Passed T, the old type of the field, and OPT its options. Returns
638 a new type for the field. */
640 static type_p
641 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
643 pair_p flds;
644 options_p nodot;
646 if (t->kind != TYPE_ARRAY)
648 error_at_line (&lexer_line,
649 "special `tree_exp' must be applied to an array");
650 return &string_type;
653 nodot = XNEW (struct options);
654 nodot->next = NULL;
655 nodot->name = "dot";
656 nodot->info = "";
658 flds = XNEW (struct pair);
659 flds->next = NULL;
660 flds->name = "";
661 flds->type = t;
662 flds->line.file = __FILE__;
663 flds->line.line = __LINE__;
664 flds->opt = XNEW (struct options);
665 flds->opt->next = nodot;
666 flds->opt->name = "length";
667 flds->opt->info = "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
669 options_p oldopt = flds->opt;
670 flds->opt = XNEW (struct options);
671 flds->opt->next = oldopt;
672 flds->opt->name = "default";
673 flds->opt->info = "";
676 new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
677 return find_structure ("tree_exp_subunion", 1);
680 /* Perform any special processing on a type T, about to become the type
681 of a field. Return the appropriate type for the field.
682 At present:
683 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
684 - Similarly for arrays of pointer-to-char;
685 - Converts structures for which a parameter is provided to
686 TYPE_PARAM_STRUCT;
687 - Handles "special" options.
690 type_p
691 adjust_field_type (type_p t, options_p opt)
693 int length_p = 0;
694 const int pointer_p = t->kind == TYPE_POINTER;
695 type_p params[NUM_PARAM];
696 int params_p = 0;
697 int i;
699 for (i = 0; i < NUM_PARAM; i++)
700 params[i] = NULL;
702 for (; opt; opt = opt->next)
703 if (strcmp (opt->name, "length") == 0)
704 length_p = 1;
705 else if (strcmp (opt->name, "param_is") == 0
706 || (strncmp (opt->name, "param", 5) == 0
707 && ISDIGIT (opt->name[5])
708 && strcmp (opt->name + 6, "_is") == 0))
710 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
712 if (! UNION_OR_STRUCT_P (t)
713 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
715 error_at_line (&lexer_line,
716 "option `%s' may only be applied to structures or structure pointers",
717 opt->name);
718 return t;
721 params_p = 1;
722 if (params[num] != NULL)
723 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
724 if (! ISDIGIT (opt->name[5]))
725 params[num] = create_pointer ((type_p) opt->info);
726 else
727 params[num] = (type_p) opt->info;
729 else if (strcmp (opt->name, "special") == 0)
731 const char *special_name = opt->info;
732 if (strcmp (special_name, "tree_exp") == 0)
733 t = adjust_field_tree_exp (t, opt);
734 else if (strcmp (special_name, "rtx_def") == 0)
735 t = adjust_field_rtx_def (t, opt);
736 else
737 error_at_line (&lexer_line, "unknown special `%s'", special_name);
740 if (params_p)
742 type_p realt;
744 if (pointer_p)
745 t = t->u.p;
746 realt = find_param_structure (t, params);
747 t = pointer_p ? create_pointer (realt) : realt;
750 if (! length_p
751 && pointer_p
752 && t->u.p->kind == TYPE_SCALAR
753 && (strcmp (t->u.p->u.sc, "char") == 0
754 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
755 return &string_type;
756 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
757 && t->u.a.p->u.p->kind == TYPE_SCALAR
758 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
759 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
760 return create_array (&string_type, t->u.a.len);
762 return t;
765 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
766 and information about the correspondence between token types and fields
767 in TYPEINFO. POS is used for error messages. */
769 void
770 note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
771 struct fileloc *pos)
773 pair_p p;
774 pair_p *p_p;
776 for (p = typeinfo; p; p = p->next)
778 pair_p m;
780 if (p->name == NULL)
781 continue;
783 if (p->type == (type_p) 1)
785 pair_p pp;
786 int ok = 0;
788 for (pp = typeinfo; pp; pp = pp->next)
789 if (pp->type != (type_p) 1
790 && strcmp (pp->opt->info, p->opt->info) == 0)
792 ok = 1;
793 break;
795 if (! ok)
796 continue;
799 for (m = fields; m; m = m->next)
800 if (strcmp (m->name, p->name) == 0)
801 p->type = m->type;
802 if (p->type == NULL)
804 error_at_line (&p->line,
805 "couldn't match fieldname `%s'", p->name);
806 p->name = NULL;
810 p_p = &typeinfo;
811 while (*p_p)
813 pair_p p = *p_p;
815 if (p->name == NULL
816 || p->type == (type_p) 1)
817 *p_p = p->next;
818 else
819 p_p = &p->next;
822 new_structure ("yy_union", 1, pos, typeinfo, o);
823 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
826 static void process_gc_options (options_p, enum gc_used_enum,
827 int *, int *, int *, type_p *);
828 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
829 static void set_gc_used (pair_p);
831 /* Handle OPT for set_gc_used_type. */
833 static void
834 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
835 int *pass_param, int *length, type_p *nested_ptr)
837 options_p o;
838 for (o = opt; o; o = o->next)
839 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
840 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
841 else if (strcmp (o->name, "maybe_undef") == 0)
842 *maybe_undef = 1;
843 else if (strcmp (o->name, "use_params") == 0)
844 *pass_param = 1;
845 else if (strcmp (o->name, "length") == 0)
846 *length = 1;
847 else if (strcmp (o->name, "nested_ptr") == 0)
848 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
851 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
853 static void
854 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
856 if (t->gc_used >= level)
857 return;
859 t->gc_used = level;
861 switch (t->kind)
863 case TYPE_STRUCT:
864 case TYPE_UNION:
866 pair_p f;
867 int dummy;
868 type_p dummy2;
870 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy,
871 &dummy2);
873 for (f = t->u.s.fields; f; f = f->next)
875 int maybe_undef = 0;
876 int pass_param = 0;
877 int length = 0;
878 type_p nested_ptr = NULL;
879 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
880 &length, &nested_ptr);
882 if (nested_ptr && f->type->kind == TYPE_POINTER)
883 set_gc_used_type (nested_ptr, GC_POINTED_TO,
884 pass_param ? param : NULL);
885 else if (length && f->type->kind == TYPE_POINTER)
886 set_gc_used_type (f->type->u.p, GC_USED, NULL);
887 else if (maybe_undef && f->type->kind == TYPE_POINTER)
888 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
889 else if (pass_param && f->type->kind == TYPE_POINTER && param)
890 set_gc_used_type (find_param_structure (f->type->u.p, param),
891 GC_POINTED_TO, NULL);
892 else
893 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
895 break;
898 case TYPE_POINTER:
899 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
900 break;
902 case TYPE_ARRAY:
903 set_gc_used_type (t->u.a.p, GC_USED, param);
904 break;
906 case TYPE_LANG_STRUCT:
907 for (t = t->u.s.lang_struct; t; t = t->next)
908 set_gc_used_type (t, level, param);
909 break;
911 case TYPE_PARAM_STRUCT:
913 int i;
914 for (i = 0; i < NUM_PARAM; i++)
915 if (t->u.param_struct.param[i] != 0)
916 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
918 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
919 level = GC_POINTED_TO;
920 else
921 level = GC_USED;
922 t->u.param_struct.stru->gc_used = GC_UNUSED;
923 set_gc_used_type (t->u.param_struct.stru, level,
924 t->u.param_struct.param);
925 break;
927 default:
928 break;
932 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
934 static void
935 set_gc_used (pair_p variables)
937 pair_p p;
938 for (p = variables; p; p = p->next)
939 set_gc_used_type (p->type, GC_USED, NULL);
942 /* File mapping routines. For each input file, there is one output .c file
943 (but some output files have many input files), and there is one .h file
944 for the whole build. */
946 /* The list of output files. */
947 static outf_p output_files;
949 /* The output header file that is included into pretty much every
950 source file. */
951 static outf_p header_file;
953 /* Number of files specified in gtfiles. */
954 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
956 /* Number of files in the language files array. */
957 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
959 /* Length of srcdir name. */
960 static int srcdir_len = 0;
962 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
963 outf_p base_files[NUM_BASE_FILES];
965 static outf_p create_file (const char *, const char *);
966 static const char * get_file_basename (const char *);
968 /* Create and return an outf_p for a new file for NAME, to be called
969 ONAME. */
971 static outf_p
972 create_file (const char *name, const char *oname)
974 static const char *const hdr[] = {
975 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
976 "\n",
977 "This file is part of GCC.\n",
978 "\n",
979 "GCC is free software; you can redistribute it and/or modify it under\n",
980 "the terms of the GNU General Public License as published by the Free\n",
981 "Software Foundation; either version 2, or (at your option) any later\n",
982 "version.\n",
983 "\n",
984 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
985 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
986 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
987 "for more details.\n",
988 "\n",
989 "You should have received a copy of the GNU General Public License\n",
990 "along with GCC; see the file COPYING. If not, write to the Free\n",
991 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
992 "02111-1307, USA. */\n",
993 "\n",
994 "/* This file is machine generated. Do not edit. */\n"
996 outf_p f;
997 size_t i;
999 f = XCNEW (struct outf);
1000 f->next = output_files;
1001 f->name = oname;
1002 output_files = f;
1004 oprintf (f, "/* Type information for %s.\n", name);
1005 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1006 oprintf (f, "%s", hdr[i]);
1007 return f;
1010 /* Print, like fprintf, to O. */
1011 void
1012 oprintf (outf_p o, const char *format, ...)
1014 char *s;
1015 size_t slength;
1016 va_list ap;
1018 va_start (ap, format);
1019 slength = xvasprintf (&s, format, ap);
1021 if (o->bufused + slength > o->buflength)
1023 size_t new_len = o->buflength;
1024 if (new_len == 0)
1025 new_len = 1024;
1026 do {
1027 new_len *= 2;
1028 } while (o->bufused + slength >= new_len);
1029 o->buf = XRESIZEVEC (char, o->buf, new_len);
1030 o->buflength = new_len;
1032 memcpy (o->buf + o->bufused, s, slength);
1033 o->bufused += slength;
1034 free (s);
1035 va_end (ap);
1038 /* Open the global header file and the language-specific header files. */
1040 static void
1041 open_base_files (void)
1043 size_t i;
1045 header_file = create_file ("GCC", "gtype-desc.h");
1047 for (i = 0; i < NUM_BASE_FILES; i++)
1048 base_files[i] = create_file (lang_dir_names[i],
1049 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1051 /* gtype-desc.c is a little special, so we create it here. */
1053 /* The order of files here matters very much. */
1054 static const char *const ifiles [] = {
1055 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1056 "hashtab.h", "splay-tree.h", "bitmap.h", "input.h", "tree.h", "rtl.h",
1057 "function.h", "insn-config.h", "expr.h", "hard-reg-set.h",
1058 "basic-block.h", "cselib.h", "insn-addr.h", "optabs.h",
1059 "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1060 "tree-alias-type.h", "tree-flow.h", "reload.h",
1061 "cpp-id-data.h",
1062 "tree-chrec.h",
1063 NULL
1065 const char *const *ifp;
1066 outf_p gtype_desc_c;
1068 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1069 for (ifp = ifiles; *ifp; ifp++)
1070 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1074 /* Determine the pathname to F relative to $(srcdir). */
1076 static const char *
1077 get_file_basename (const char *f)
1079 const char *basename;
1080 unsigned i;
1082 basename = strrchr (f, '/');
1084 if (!basename)
1085 return f;
1087 basename++;
1089 for (i = 1; i < NUM_BASE_FILES; i++)
1091 const char * s1;
1092 const char * s2;
1093 int l1;
1094 int l2;
1095 s1 = basename - strlen (lang_dir_names [i]) - 1;
1096 s2 = lang_dir_names [i];
1097 l1 = strlen (s1);
1098 l2 = strlen (s2);
1099 if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1101 basename -= l2 + 1;
1102 if ((basename - f - 1) != srcdir_len)
1103 abort (); /* Match is wrong - should be preceded by $srcdir. */
1104 break;
1108 return basename;
1111 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1112 INPUT_FILE is used by <lang>.
1114 This function should be written to assume that a file _is_ used
1115 if the situation is unclear. If it wrongly assumes a file _is_ used,
1116 a linker error will result. If it wrongly assumes a file _is not_ used,
1117 some GC roots may be missed, which is a much harder-to-debug problem. */
1119 unsigned
1120 get_base_file_bitmap (const char *input_file)
1122 const char *basename = get_file_basename (input_file);
1123 const char *slashpos = strchr (basename, '/');
1124 unsigned j;
1125 unsigned k;
1126 unsigned bitmap;
1128 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1129 it belongs to the corresponding language. The file may belong to other
1130 languages as well (which is checked for below). */
1132 if (slashpos)
1134 size_t i;
1135 for (i = 1; i < NUM_BASE_FILES; i++)
1136 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1137 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1139 /* It's in a language directory, set that language. */
1140 bitmap = 1 << i;
1144 /* If it's in any config-lang.in, then set for the languages
1145 specified. */
1147 bitmap = 0;
1149 for (j = 0; j < NUM_LANG_FILES; j++)
1151 if (!strcmp(input_file, lang_files[j]))
1153 for (k = 0; k < NUM_BASE_FILES; k++)
1155 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1156 bitmap |= (1 << k);
1161 /* Otherwise, set all languages. */
1162 if (!bitmap)
1163 bitmap = (1 << NUM_BASE_FILES) - 1;
1165 return bitmap;
1168 /* An output file, suitable for definitions, that can see declarations
1169 made in INPUT_FILE and is linked into every language that uses
1170 INPUT_FILE. */
1172 outf_p
1173 get_output_file_with_visibility (const char *input_file)
1175 outf_p r;
1176 size_t len;
1177 const char *basename;
1178 const char *for_name;
1179 const char *output_name;
1181 /* This can happen when we need a file with visibility on a
1182 structure that we've never seen. We have to just hope that it's
1183 globally visible. */
1184 if (input_file == NULL)
1185 input_file = "system.h";
1187 /* Determine the output file name. */
1188 basename = get_file_basename (input_file);
1190 len = strlen (basename);
1191 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1192 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1193 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1195 char *s;
1197 output_name = s = xasprintf ("gt-%s", basename);
1198 for (; *s != '.'; s++)
1199 if (! ISALNUM (*s) && *s != '-')
1200 *s = '-';
1201 memcpy (s, ".h", sizeof (".h"));
1202 for_name = basename;
1204 /* Some headers get used by more than one front-end; hence, it
1205 would be inappropriate to spew them out to a single gtype-<lang>.h
1206 (and gengtype doesn't know how to direct spewage into multiple
1207 gtype-<lang>.h headers at this time). Instead, we pair up these
1208 headers with source files (and their special purpose gt-*.h headers). */
1209 else if (strcmp (basename, "c-common.h") == 0)
1210 output_name = "gt-c-common.h", for_name = "c-common.c";
1211 else if (strcmp (basename, "c-tree.h") == 0)
1212 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1213 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1214 && strcmp (basename + 5, "objc-act.h") == 0)
1215 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1216 else
1218 size_t i;
1220 for (i = 0; i < NUM_BASE_FILES; i++)
1221 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1222 && basename[strlen(lang_dir_names[i])] == '/')
1223 return base_files[i];
1225 output_name = "gtype-desc.c";
1226 for_name = NULL;
1229 /* Look through to see if we've ever seen this output filename before. */
1230 for (r = output_files; r; r = r->next)
1231 if (strcmp (r->name, output_name) == 0)
1232 return r;
1234 /* If not, create it. */
1235 r = create_file (for_name, output_name);
1237 return r;
1240 /* The name of an output file, suitable for definitions, that can see
1241 declarations made in INPUT_FILE and is linked into every language
1242 that uses INPUT_FILE. */
1244 const char *
1245 get_output_file_name (const char *input_file)
1247 return get_output_file_with_visibility (input_file)->name;
1250 /* Copy the output to its final destination,
1251 but don't unnecessarily change modification times. */
1253 static void
1254 close_output_files (void)
1256 outf_p of;
1258 for (of = output_files; of; of = of->next)
1260 FILE * newfile;
1262 newfile = fopen (of->name, "r");
1263 if (newfile != NULL )
1265 int no_write_p;
1266 size_t i;
1268 for (i = 0; i < of->bufused; i++)
1270 int ch;
1271 ch = fgetc (newfile);
1272 if (ch == EOF || ch != (unsigned char) of->buf[i])
1273 break;
1275 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1276 fclose (newfile);
1278 if (no_write_p)
1279 continue;
1282 newfile = fopen (of->name, "w");
1283 if (newfile == NULL)
1285 perror ("opening output file");
1286 exit (1);
1288 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1290 perror ("writing output file");
1291 exit (1);
1293 if (fclose (newfile) != 0)
1295 perror ("closing output file");
1296 exit (1);
1301 struct flist {
1302 struct flist *next;
1303 int started_p;
1304 const char *name;
1305 outf_p f;
1308 struct walk_type_data;
1310 /* For scalars and strings, given the item in 'val'.
1311 For structures, given a pointer to the item in 'val'.
1312 For misc. pointers, given the item in 'val'.
1314 typedef void (*process_field_fn)
1315 (type_p f, const struct walk_type_data *p);
1316 typedef void (*func_name_fn)
1317 (type_p s, const struct walk_type_data *p);
1319 /* Parameters for write_types. */
1321 struct write_types_data
1323 const char *prefix;
1324 const char *param_prefix;
1325 const char *subfield_marker_routine;
1326 const char *marker_routine;
1327 const char *reorder_note_routine;
1328 const char *comment;
1331 static void output_escaped_param (struct walk_type_data *d,
1332 const char *, const char *);
1333 static void output_mangled_typename (outf_p, type_p);
1334 static void walk_type (type_p t, struct walk_type_data *d);
1335 static void write_func_for_structure
1336 (type_p orig_s, type_p s, type_p * param,
1337 const struct write_types_data *wtd);
1338 static void write_types_process_field
1339 (type_p f, const struct walk_type_data *d);
1340 static void write_types (type_p structures,
1341 type_p param_structs,
1342 const struct write_types_data *wtd);
1343 static void write_types_local_process_field
1344 (type_p f, const struct walk_type_data *d);
1345 static void write_local_func_for_structure
1346 (type_p orig_s, type_p s, type_p * param);
1347 static void write_local (type_p structures,
1348 type_p param_structs);
1349 static void write_enum_defn (type_p structures, type_p param_structs);
1350 static int contains_scalar_p (type_p t);
1351 static void put_mangled_filename (outf_p , const char *);
1352 static void finish_root_table (struct flist *flp, const char *pfx,
1353 const char *tname, const char *lastname,
1354 const char *name);
1355 static void write_root (outf_p , pair_p, type_p, const char *, int,
1356 struct fileloc *, const char *);
1357 static void write_array (outf_p f, pair_p v,
1358 const struct write_types_data *wtd);
1359 static void write_roots (pair_p);
1361 /* Parameters for walk_type. */
1363 struct walk_type_data
1365 process_field_fn process_field;
1366 const void *cookie;
1367 outf_p of;
1368 options_p opt;
1369 const char *val;
1370 const char *prev_val[4];
1371 int indent;
1372 int counter;
1373 struct fileloc *line;
1374 lang_bitmap bitmap;
1375 type_p *param;
1376 int used_length;
1377 type_p orig_s;
1378 const char *reorder_fn;
1379 bool needs_cast_p;
1380 bool fn_wants_lvalue;
1383 /* Print a mangled name representing T to OF. */
1385 static void
1386 output_mangled_typename (outf_p of, type_p t)
1388 if (t == NULL)
1389 oprintf (of, "Z");
1390 else switch (t->kind)
1392 case TYPE_POINTER:
1393 oprintf (of, "P");
1394 output_mangled_typename (of, t->u.p);
1395 break;
1396 case TYPE_SCALAR:
1397 oprintf (of, "I");
1398 break;
1399 case TYPE_STRING:
1400 oprintf (of, "S");
1401 break;
1402 case TYPE_STRUCT:
1403 case TYPE_UNION:
1404 case TYPE_LANG_STRUCT:
1405 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1406 break;
1407 case TYPE_PARAM_STRUCT:
1409 int i;
1410 for (i = 0; i < NUM_PARAM; i++)
1411 if (t->u.param_struct.param[i] != NULL)
1412 output_mangled_typename (of, t->u.param_struct.param[i]);
1413 output_mangled_typename (of, t->u.param_struct.stru);
1415 break;
1416 case TYPE_ARRAY:
1417 abort ();
1421 /* Print PARAM to D->OF processing escapes. D->VAL references the
1422 current object, D->PREV_VAL the object containing the current
1423 object, ONAME is the name of the option and D->LINE is used to
1424 print error messages. */
1426 static void
1427 output_escaped_param (struct walk_type_data *d, const char *param,
1428 const char *oname)
1430 const char *p;
1432 for (p = param; *p; p++)
1433 if (*p != '%')
1434 oprintf (d->of, "%c", *p);
1435 else switch (*++p)
1437 case 'h':
1438 oprintf (d->of, "(%s)", d->prev_val[2]);
1439 break;
1440 case '0':
1441 oprintf (d->of, "(%s)", d->prev_val[0]);
1442 break;
1443 case '1':
1444 oprintf (d->of, "(%s)", d->prev_val[1]);
1445 break;
1446 case 'a':
1448 const char *pp = d->val + strlen (d->val);
1449 while (pp[-1] == ']')
1450 while (*pp != '[')
1451 pp--;
1452 oprintf (d->of, "%s", pp);
1454 break;
1455 default:
1456 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1457 oname, '%', *p);
1461 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1462 which is of type T. Write code to D->OF to constrain execution (at
1463 the point that D->PROCESS_FIELD is called) to the appropriate
1464 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1465 pointers to those objects. D->PREV_VAL lists the objects
1466 containing the current object, D->OPT is a list of options to
1467 apply, D->INDENT is the current indentation level, D->LINE is used
1468 to print error messages, D->BITMAP indicates which languages to
1469 print the structure for, and D->PARAM is the current parameter
1470 (from an enclosing param_is option). */
1472 static void
1473 walk_type (type_p t, struct walk_type_data *d)
1475 const char *length = NULL;
1476 const char *desc = NULL;
1477 int maybe_undef_p = 0;
1478 int use_param_num = -1;
1479 int use_params_p = 0;
1480 options_p oo;
1481 const struct nested_ptr_data *nested_ptr_d = NULL;
1483 d->needs_cast_p = false;
1484 for (oo = d->opt; oo; oo = oo->next)
1485 if (strcmp (oo->name, "length") == 0)
1486 length = oo->info;
1487 else if (strcmp (oo->name, "maybe_undef") == 0)
1488 maybe_undef_p = 1;
1489 else if (strncmp (oo->name, "use_param", 9) == 0
1490 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1491 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1492 else if (strcmp (oo->name, "use_params") == 0)
1493 use_params_p = 1;
1494 else if (strcmp (oo->name, "desc") == 0)
1495 desc = oo->info;
1496 else if (strcmp (oo->name, "nested_ptr") == 0)
1497 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1498 else if (strcmp (oo->name, "dot") == 0)
1500 else if (strcmp (oo->name, "tag") == 0)
1502 else if (strcmp (oo->name, "special") == 0)
1504 else if (strcmp (oo->name, "skip") == 0)
1506 else if (strcmp (oo->name, "default") == 0)
1508 else if (strcmp (oo->name, "descbits") == 0)
1510 else if (strcmp (oo->name, "param_is") == 0)
1512 else if (strncmp (oo->name, "param", 5) == 0
1513 && ISDIGIT (oo->name[5])
1514 && strcmp (oo->name + 6, "_is") == 0)
1516 else if (strcmp (oo->name, "chain_next") == 0)
1518 else if (strcmp (oo->name, "chain_prev") == 0)
1520 else if (strcmp (oo->name, "reorder") == 0)
1522 else
1523 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1525 if (d->used_length)
1526 length = NULL;
1528 if (use_params_p)
1530 int pointer_p = t->kind == TYPE_POINTER;
1532 if (pointer_p)
1533 t = t->u.p;
1534 if (! UNION_OR_STRUCT_P (t))
1535 error_at_line (d->line, "`use_params' option on unimplemented type");
1536 else
1537 t = find_param_structure (t, d->param);
1538 if (pointer_p)
1539 t = create_pointer (t);
1542 if (use_param_num != -1)
1544 if (d->param != NULL && d->param[use_param_num] != NULL)
1546 type_p nt = d->param[use_param_num];
1548 if (t->kind == TYPE_ARRAY)
1549 nt = create_array (nt, t->u.a.len);
1550 else if (length != NULL && t->kind == TYPE_POINTER)
1551 nt = create_pointer (nt);
1552 d->needs_cast_p = (t->kind != TYPE_POINTER
1553 && (nt->kind == TYPE_POINTER
1554 || nt->kind == TYPE_STRING));
1555 t = nt;
1557 else
1558 error_at_line (d->line, "no parameter defined for `%s'",
1559 d->val);
1562 if (maybe_undef_p
1563 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1565 error_at_line (d->line,
1566 "field `%s' has invalid option `maybe_undef_p'\n",
1567 d->val);
1568 return;
1571 switch (t->kind)
1573 case TYPE_SCALAR:
1574 case TYPE_STRING:
1575 d->process_field (t, d);
1576 break;
1578 case TYPE_POINTER:
1580 if (maybe_undef_p
1581 && t->u.p->u.s.line.file == NULL)
1583 oprintf (d->of, "%*sif (%s) abort();\n", d->indent, "", d->val);
1584 break;
1587 if (! length)
1589 if (! UNION_OR_STRUCT_P (t->u.p)
1590 && t->u.p->kind != TYPE_PARAM_STRUCT)
1592 error_at_line (d->line,
1593 "field `%s' is pointer to unimplemented type",
1594 d->val);
1595 break;
1598 if (nested_ptr_d)
1600 const char *oldprevval2 = d->prev_val[2];
1602 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1604 error_at_line (d->line,
1605 "field `%s' has invalid "
1606 "option `nested_ptr'\n",
1607 d->val);
1608 return;
1611 d->prev_val[2] = d->val;
1612 oprintf (d->of, "%*s{\n", d->indent, "");
1613 d->indent += 2;
1614 d->val = xasprintf ("x%d", d->counter++);
1615 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1616 (nested_ptr_d->type->kind == TYPE_UNION
1617 ? "union" : "struct"),
1618 nested_ptr_d->type->u.s.tag,
1619 d->fn_wants_lvalue ? "" : "const ",
1620 d->val);
1621 oprintf (d->of, "%*s", d->indent + 2, "");
1622 output_escaped_param (d, nested_ptr_d->convert_from,
1623 "nested_ptr");
1624 oprintf (d->of, ";\n");
1626 d->process_field (nested_ptr_d->type, d);
1628 if (d->fn_wants_lvalue)
1630 oprintf (d->of, "%*s%s = ", d->indent, "",
1631 d->prev_val[2]);
1632 d->prev_val[2] = d->val;
1633 output_escaped_param (d, nested_ptr_d->convert_to,
1634 "nested_ptr");
1635 oprintf (d->of, ";\n");
1638 d->indent -= 2;
1639 oprintf (d->of, "%*s}\n", d->indent, "");
1640 d->val = d->prev_val[2];
1641 d->prev_val[2] = oldprevval2;
1643 else
1644 d->process_field (t->u.p, d);
1646 else
1648 int loopcounter = d->counter++;
1649 const char *oldval = d->val;
1650 const char *oldprevval3 = d->prev_val[3];
1651 char *newval;
1653 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1654 d->indent += 2;
1655 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1656 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1657 loopcounter, loopcounter);
1658 output_escaped_param (d, length, "length");
1659 oprintf (d->of, "); i%d++) {\n", loopcounter);
1660 d->indent += 2;
1661 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1662 d->used_length = 1;
1663 d->prev_val[3] = oldval;
1664 walk_type (t->u.p, d);
1665 free (newval);
1666 d->val = oldval;
1667 d->prev_val[3] = oldprevval3;
1668 d->used_length = 0;
1669 d->indent -= 2;
1670 oprintf (d->of, "%*s}\n", d->indent, "");
1671 d->process_field(t, d);
1672 d->indent -= 2;
1673 oprintf (d->of, "%*s}\n", d->indent, "");
1676 break;
1678 case TYPE_ARRAY:
1680 int loopcounter = d->counter++;
1681 const char *oldval = d->val;
1682 char *newval;
1684 /* If it's an array of scalars, we optimize by not generating
1685 any code. */
1686 if (t->u.a.p->kind == TYPE_SCALAR)
1687 break;
1689 oprintf (d->of, "%*s{\n", d->indent, "");
1690 d->indent += 2;
1691 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1692 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1693 loopcounter, loopcounter);
1694 if (length)
1695 output_escaped_param (d, length, "length");
1696 else
1697 oprintf (d->of, "%s", t->u.a.len);
1698 oprintf (d->of, "); i%d++) {\n", loopcounter);
1699 d->indent += 2;
1700 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1701 d->used_length = 1;
1702 walk_type (t->u.a.p, d);
1703 free (newval);
1704 d->used_length = 0;
1705 d->val = oldval;
1706 d->indent -= 2;
1707 oprintf (d->of, "%*s}\n", d->indent, "");
1708 d->indent -= 2;
1709 oprintf (d->of, "%*s}\n", d->indent, "");
1711 break;
1713 case TYPE_STRUCT:
1714 case TYPE_UNION:
1716 pair_p f;
1717 const char *oldval = d->val;
1718 const char *oldprevval1 = d->prev_val[1];
1719 const char *oldprevval2 = d->prev_val[2];
1720 const int union_p = t->kind == TYPE_UNION;
1721 int seen_default_p = 0;
1722 options_p o;
1724 if (! t->u.s.line.file)
1725 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1727 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1729 error_at_line (d->line,
1730 "structure `%s' defined for mismatching languages",
1731 t->u.s.tag);
1732 error_at_line (&t->u.s.line, "one structure defined here");
1735 /* Some things may also be defined in the structure's options. */
1736 for (o = t->u.s.opt; o; o = o->next)
1737 if (! desc && strcmp (o->name, "desc") == 0)
1738 desc = o->info;
1740 d->prev_val[2] = oldval;
1741 d->prev_val[1] = oldprevval2;
1742 if (union_p)
1744 if (desc == NULL)
1746 error_at_line (d->line, "missing `desc' option for union `%s'",
1747 t->u.s.tag);
1748 desc = "1";
1750 oprintf (d->of, "%*sswitch (", d->indent, "");
1751 output_escaped_param (d, desc, "desc");
1752 oprintf (d->of, ")\n");
1753 d->indent += 2;
1754 oprintf (d->of, "%*s{\n", d->indent, "");
1756 for (f = t->u.s.fields; f; f = f->next)
1758 options_p oo;
1759 const char *dot = ".";
1760 const char *tagid = NULL;
1761 int skip_p = 0;
1762 int default_p = 0;
1763 int use_param_p = 0;
1764 char *newval;
1766 d->reorder_fn = NULL;
1767 for (oo = f->opt; oo; oo = oo->next)
1768 if (strcmp (oo->name, "dot") == 0)
1769 dot = oo->info;
1770 else if (strcmp (oo->name, "tag") == 0)
1771 tagid = oo->info;
1772 else if (strcmp (oo->name, "skip") == 0)
1773 skip_p = 1;
1774 else if (strcmp (oo->name, "default") == 0)
1775 default_p = 1;
1776 else if (strcmp (oo->name, "reorder") == 0)
1777 d->reorder_fn = oo->info;
1778 else if (strncmp (oo->name, "use_param", 9) == 0
1779 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1780 use_param_p = 1;
1782 if (skip_p)
1783 continue;
1785 if (union_p && tagid)
1787 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1788 d->indent += 2;
1790 else if (union_p && default_p)
1792 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1793 d->indent += 2;
1794 seen_default_p = 1;
1796 else if (! union_p && (default_p || tagid))
1797 error_at_line (d->line,
1798 "can't use `%s' outside a union on field `%s'",
1799 default_p ? "default" : "tag", f->name);
1800 else if (union_p && ! (default_p || tagid)
1801 && f->type->kind == TYPE_SCALAR)
1803 fprintf (stderr,
1804 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1805 d->line->file, d->line->line, f->name);
1806 continue;
1808 else if (union_p && ! (default_p || tagid))
1809 error_at_line (d->line,
1810 "field `%s' is missing `tag' or `default' option",
1811 f->name);
1813 d->line = &f->line;
1814 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1815 d->opt = f->opt;
1816 d->used_length = false;
1818 if (union_p && use_param_p && d->param == NULL)
1819 oprintf (d->of, "%*sabort();\n", d->indent, "");
1820 else
1821 walk_type (f->type, d);
1823 free (newval);
1825 if (union_p)
1827 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1828 d->indent -= 2;
1831 d->reorder_fn = NULL;
1833 d->val = oldval;
1834 d->prev_val[1] = oldprevval1;
1835 d->prev_val[2] = oldprevval2;
1837 if (union_p && ! seen_default_p)
1839 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1840 oprintf (d->of, "%*s break;\n", d->indent, "");
1842 if (union_p)
1844 oprintf (d->of, "%*s}\n", d->indent, "");
1845 d->indent -= 2;
1848 break;
1850 case TYPE_LANG_STRUCT:
1852 type_p nt;
1853 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1854 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1855 break;
1856 if (nt == NULL)
1857 error_at_line (d->line, "structure `%s' differs between languages",
1858 t->u.s.tag);
1859 else
1860 walk_type (nt, d);
1862 break;
1864 case TYPE_PARAM_STRUCT:
1866 type_p *oldparam = d->param;
1868 d->param = t->u.param_struct.param;
1869 walk_type (t->u.param_struct.stru, d);
1870 d->param = oldparam;
1872 break;
1874 default:
1875 abort ();
1879 /* process_field routine for marking routines. */
1881 static void
1882 write_types_process_field (type_p f, const struct walk_type_data *d)
1884 const struct write_types_data *wtd;
1885 const char *cast = d->needs_cast_p ? "(void *)" : "";
1886 wtd = (const struct write_types_data *) d->cookie;
1888 switch (f->kind)
1890 case TYPE_POINTER:
1891 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1892 wtd->subfield_marker_routine, cast, d->val);
1893 if (wtd->param_prefix)
1895 oprintf (d->of, ", %s", d->prev_val[3]);
1896 if (d->orig_s)
1898 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1899 output_mangled_typename (d->of, d->orig_s);
1901 else
1902 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1904 oprintf (d->of, ");\n");
1905 if (d->reorder_fn && wtd->reorder_note_routine)
1906 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1907 wtd->reorder_note_routine, cast, d->val,
1908 d->prev_val[3], d->reorder_fn);
1909 break;
1911 case TYPE_STRING:
1912 if (wtd->param_prefix == NULL)
1913 break;
1915 case TYPE_STRUCT:
1916 case TYPE_UNION:
1917 case TYPE_LANG_STRUCT:
1918 case TYPE_PARAM_STRUCT:
1919 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1920 output_mangled_typename (d->of, f);
1921 oprintf (d->of, " (%s%s);\n", cast, d->val);
1922 if (d->reorder_fn && wtd->reorder_note_routine)
1923 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1924 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1925 d->reorder_fn);
1926 break;
1928 case TYPE_SCALAR:
1929 break;
1931 default:
1932 abort ();
1936 /* For S, a structure that's part of ORIG_S, and using parameters
1937 PARAM, write out a routine that:
1938 - Takes a parameter, a void * but actually of type *S
1939 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1940 field of S or its substructures and (in some cases) things
1941 that are pointed to by S.
1944 static void
1945 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
1946 const struct write_types_data *wtd)
1948 const char *fn = s->u.s.line.file;
1949 int i;
1950 const char *chain_next = NULL;
1951 const char *chain_prev = NULL;
1952 options_p opt;
1953 struct walk_type_data d;
1955 /* This is a hack, and not the good kind either. */
1956 for (i = NUM_PARAM - 1; i >= 0; i--)
1957 if (param && param[i] && param[i]->kind == TYPE_POINTER
1958 && UNION_OR_STRUCT_P (param[i]->u.p))
1959 fn = param[i]->u.p->u.s.line.file;
1961 memset (&d, 0, sizeof (d));
1962 d.of = get_output_file_with_visibility (fn);
1964 for (opt = s->u.s.opt; opt; opt = opt->next)
1965 if (strcmp (opt->name, "chain_next") == 0)
1966 chain_next = opt->info;
1967 else if (strcmp (opt->name, "chain_prev") == 0)
1968 chain_prev = opt->info;
1970 if (chain_prev != NULL && chain_next == NULL)
1971 error_at_line (&s->u.s.line, "chain_prev without chain_next");
1973 d.process_field = write_types_process_field;
1974 d.cookie = wtd;
1975 d.orig_s = orig_s;
1976 d.opt = s->u.s.opt;
1977 d.line = &s->u.s.line;
1978 d.bitmap = s->u.s.bitmap;
1979 d.param = param;
1980 d.prev_val[0] = "*x";
1981 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
1982 d.prev_val[3] = "x";
1983 d.val = "(*x)";
1985 oprintf (d.of, "\n");
1986 oprintf (d.of, "void\n");
1987 if (param == NULL)
1988 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
1989 else
1991 oprintf (d.of, "gt_%s_", wtd->prefix);
1992 output_mangled_typename (d.of, orig_s);
1994 oprintf (d.of, " (void *x_p)\n");
1995 oprintf (d.of, "{\n");
1996 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
1997 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1998 chain_next == NULL ? "const " : "",
1999 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2000 if (chain_next != NULL)
2001 oprintf (d.of, " %s %s * xlimit = x;\n",
2002 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2003 if (chain_next == NULL)
2005 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2006 if (wtd->param_prefix)
2008 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2009 output_mangled_typename (d.of, orig_s);
2011 oprintf (d.of, "))\n");
2013 else
2015 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2016 if (wtd->param_prefix)
2018 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2019 output_mangled_typename (d.of, orig_s);
2021 oprintf (d.of, "))\n");
2022 oprintf (d.of, " xlimit = (");
2023 d.prev_val[2] = "*xlimit";
2024 output_escaped_param (&d, chain_next, "chain_next");
2025 oprintf (d.of, ");\n");
2026 if (chain_prev != NULL)
2028 oprintf (d.of, " if (x != xlimit)\n");
2029 oprintf (d.of, " for (;;)\n");
2030 oprintf (d.of, " {\n");
2031 oprintf (d.of, " %s %s * const xprev = (",
2032 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2034 d.prev_val[2] = "*x";
2035 output_escaped_param (&d, chain_prev, "chain_prev");
2036 oprintf (d.of, ");\n");
2037 oprintf (d.of, " if (xprev == NULL) break;\n");
2038 oprintf (d.of, " x = xprev;\n");
2039 oprintf (d.of, " (void) %s (xprev",
2040 wtd->marker_routine);
2041 if (wtd->param_prefix)
2043 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2044 output_mangled_typename (d.of, orig_s);
2046 oprintf (d.of, ");\n");
2047 oprintf (d.of, " }\n");
2049 oprintf (d.of, " while (x != xlimit)\n");
2051 oprintf (d.of, " {\n");
2053 d.prev_val[2] = "*x";
2054 d.indent = 6;
2055 walk_type (s, &d);
2057 if (chain_next != NULL)
2059 oprintf (d.of, " x = (");
2060 output_escaped_param (&d, chain_next, "chain_next");
2061 oprintf (d.of, ");\n");
2064 oprintf (d.of, " }\n");
2065 oprintf (d.of, "}\n");
2068 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2070 static void
2071 write_types (type_p structures, type_p param_structs,
2072 const struct write_types_data *wtd)
2074 type_p s;
2076 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2077 for (s = structures; s; s = s->next)
2078 if (s->gc_used == GC_POINTED_TO
2079 || s->gc_used == GC_MAYBE_POINTED_TO)
2081 options_p opt;
2083 if (s->gc_used == GC_MAYBE_POINTED_TO
2084 && s->u.s.line.file == NULL)
2085 continue;
2087 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2088 output_mangled_typename (header_file, s);
2089 oprintf (header_file, "(X) do { \\\n");
2090 oprintf (header_file,
2091 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2092 s->u.s.tag);
2093 oprintf (header_file,
2094 " } while (0)\n");
2096 for (opt = s->u.s.opt; opt; opt = opt->next)
2097 if (strcmp (opt->name, "ptr_alias") == 0)
2099 type_p t = (type_p) opt->info;
2100 if (t->kind == TYPE_STRUCT
2101 || t->kind == TYPE_UNION
2102 || t->kind == TYPE_LANG_STRUCT)
2103 oprintf (header_file,
2104 "#define gt_%sx_%s gt_%sx_%s\n",
2105 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2106 else
2107 error_at_line (&s->u.s.line,
2108 "structure alias is not a structure");
2109 break;
2111 if (opt)
2112 continue;
2114 /* Declare the marker procedure only once. */
2115 oprintf (header_file,
2116 "extern void gt_%sx_%s (void *);\n",
2117 wtd->prefix, s->u.s.tag);
2119 if (s->u.s.line.file == NULL)
2121 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2122 s->u.s.tag);
2123 continue;
2126 if (s->kind == TYPE_LANG_STRUCT)
2128 type_p ss;
2129 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2130 write_func_for_structure (s, ss, NULL, wtd);
2132 else
2133 write_func_for_structure (s, s, NULL, wtd);
2136 for (s = param_structs; s; s = s->next)
2137 if (s->gc_used == GC_POINTED_TO)
2139 type_p * param = s->u.param_struct.param;
2140 type_p stru = s->u.param_struct.stru;
2142 /* Declare the marker procedure. */
2143 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2144 output_mangled_typename (header_file, s);
2145 oprintf (header_file, " (void *);\n");
2147 if (stru->u.s.line.file == NULL)
2149 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2150 s->u.s.tag);
2151 continue;
2154 if (stru->kind == TYPE_LANG_STRUCT)
2156 type_p ss;
2157 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2158 write_func_for_structure (s, ss, param, wtd);
2160 else
2161 write_func_for_structure (s, stru, param, wtd);
2165 static const struct write_types_data ggc_wtd =
2167 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2168 "GC marker procedures. "
2171 static const struct write_types_data pch_wtd =
2173 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2174 "gt_pch_note_reorder",
2175 "PCH type-walking procedures. "
2178 /* Write out the local pointer-walking routines. */
2180 /* process_field routine for local pointer-walking. */
2182 static void
2183 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2185 switch (f->kind)
2187 case TYPE_POINTER:
2188 case TYPE_STRUCT:
2189 case TYPE_UNION:
2190 case TYPE_LANG_STRUCT:
2191 case TYPE_PARAM_STRUCT:
2192 case TYPE_STRING:
2193 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2194 d->prev_val[3]);
2195 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2196 break;
2198 case TYPE_SCALAR:
2199 break;
2201 default:
2202 abort ();
2206 /* For S, a structure that's part of ORIG_S, and using parameters
2207 PARAM, write out a routine that:
2208 - Is of type gt_note_pointers
2209 - Calls PROCESS_FIELD on each field of S or its substructures.
2212 static void
2213 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2215 const char *fn = s->u.s.line.file;
2216 int i;
2217 struct walk_type_data d;
2219 /* This is a hack, and not the good kind either. */
2220 for (i = NUM_PARAM - 1; i >= 0; i--)
2221 if (param && param[i] && param[i]->kind == TYPE_POINTER
2222 && UNION_OR_STRUCT_P (param[i]->u.p))
2223 fn = param[i]->u.p->u.s.line.file;
2225 memset (&d, 0, sizeof (d));
2226 d.of = get_output_file_with_visibility (fn);
2228 d.process_field = write_types_local_process_field;
2229 d.opt = s->u.s.opt;
2230 d.line = &s->u.s.line;
2231 d.bitmap = s->u.s.bitmap;
2232 d.param = param;
2233 d.prev_val[0] = d.prev_val[2] = "*x";
2234 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2235 d.prev_val[3] = "x";
2236 d.val = "(*x)";
2237 d.fn_wants_lvalue = true;
2239 oprintf (d.of, "\n");
2240 oprintf (d.of, "void\n");
2241 oprintf (d.of, "gt_pch_p_");
2242 output_mangled_typename (d.of, orig_s);
2243 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2244 "\tvoid *x_p,\n"
2245 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2246 "\tATTRIBUTE_UNUSED void *cookie)\n");
2247 oprintf (d.of, "{\n");
2248 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2249 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2250 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2251 d.indent = 2;
2252 walk_type (s, &d);
2253 oprintf (d.of, "}\n");
2256 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2258 static void
2259 write_local (type_p structures, type_p param_structs)
2261 type_p s;
2263 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2264 for (s = structures; s; s = s->next)
2265 if (s->gc_used == GC_POINTED_TO
2266 || s->gc_used == GC_MAYBE_POINTED_TO)
2268 options_p opt;
2270 if (s->u.s.line.file == NULL)
2271 continue;
2273 for (opt = s->u.s.opt; opt; opt = opt->next)
2274 if (strcmp (opt->name, "ptr_alias") == 0)
2276 type_p t = (type_p) opt->info;
2277 if (t->kind == TYPE_STRUCT
2278 || t->kind == TYPE_UNION
2279 || t->kind == TYPE_LANG_STRUCT)
2281 oprintf (header_file, "#define gt_pch_p_");
2282 output_mangled_typename (header_file, s);
2283 oprintf (header_file, " gt_pch_p_");
2284 output_mangled_typename (header_file, t);
2285 oprintf (header_file, "\n");
2287 else
2288 error_at_line (&s->u.s.line,
2289 "structure alias is not a structure");
2290 break;
2292 if (opt)
2293 continue;
2295 /* Declare the marker procedure only once. */
2296 oprintf (header_file, "extern void gt_pch_p_");
2297 output_mangled_typename (header_file, s);
2298 oprintf (header_file,
2299 "\n (void *, void *, gt_pointer_operator, void *);\n");
2301 if (s->kind == TYPE_LANG_STRUCT)
2303 type_p ss;
2304 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2305 write_local_func_for_structure (s, ss, NULL);
2307 else
2308 write_local_func_for_structure (s, s, NULL);
2311 for (s = param_structs; s; s = s->next)
2312 if (s->gc_used == GC_POINTED_TO)
2314 type_p * param = s->u.param_struct.param;
2315 type_p stru = s->u.param_struct.stru;
2317 /* Declare the marker procedure. */
2318 oprintf (header_file, "extern void gt_pch_p_");
2319 output_mangled_typename (header_file, s);
2320 oprintf (header_file,
2321 "\n (void *, void *, gt_pointer_operator, void *);\n");
2323 if (stru->u.s.line.file == NULL)
2325 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2326 s->u.s.tag);
2327 continue;
2330 if (stru->kind == TYPE_LANG_STRUCT)
2332 type_p ss;
2333 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2334 write_local_func_for_structure (s, ss, param);
2336 else
2337 write_local_func_for_structure (s, stru, param);
2341 /* Write out the 'enum' definition for gt_types_enum. */
2343 static void
2344 write_enum_defn (type_p structures, type_p param_structs)
2346 type_p s;
2348 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2349 oprintf (header_file, "enum gt_types_enum {\n");
2350 for (s = structures; s; s = s->next)
2351 if (s->gc_used == GC_POINTED_TO
2352 || s->gc_used == GC_MAYBE_POINTED_TO)
2354 if (s->gc_used == GC_MAYBE_POINTED_TO
2355 && s->u.s.line.file == NULL)
2356 continue;
2358 oprintf (header_file, " gt_ggc_e_");
2359 output_mangled_typename (header_file, s);
2360 oprintf (header_file, ", \n");
2362 for (s = param_structs; s; s = s->next)
2363 if (s->gc_used == GC_POINTED_TO)
2365 oprintf (header_file, " gt_e_");
2366 output_mangled_typename (header_file, s);
2367 oprintf (header_file, ", \n");
2369 oprintf (header_file, " gt_types_enum_last\n");
2370 oprintf (header_file, "};\n");
2373 /* Might T contain any non-pointer elements? */
2375 static int
2376 contains_scalar_p (type_p t)
2378 switch (t->kind)
2380 case TYPE_STRING:
2381 case TYPE_POINTER:
2382 return 0;
2383 case TYPE_ARRAY:
2384 return contains_scalar_p (t->u.a.p);
2385 default:
2386 /* Could also check for structures that have no non-pointer
2387 fields, but there aren't enough of those to worry about. */
2388 return 1;
2392 /* Mangle FN and print it to F. */
2394 static void
2395 put_mangled_filename (outf_p f, const char *fn)
2397 const char *name = get_output_file_name (fn);
2398 for (; *name != 0; name++)
2399 if (ISALNUM (*name))
2400 oprintf (f, "%c", *name);
2401 else
2402 oprintf (f, "%c", '_');
2405 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2406 LASTNAME, and NAME are all strings to insert in various places in
2407 the resulting code. */
2409 static void
2410 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2411 const char *tname, const char *name)
2413 struct flist *fli2;
2415 for (fli2 = flp; fli2; fli2 = fli2->next)
2416 if (fli2->started_p)
2418 oprintf (fli2->f, " %s\n", lastname);
2419 oprintf (fli2->f, "};\n\n");
2422 for (fli2 = flp; fli2; fli2 = fli2->next)
2423 if (fli2->started_p)
2425 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2426 int fnum;
2428 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2429 if (bitmap & 1)
2431 oprintf (base_files[fnum],
2432 "extern const struct %s gt_%s_",
2433 tname, pfx);
2434 put_mangled_filename (base_files[fnum], fli2->name);
2435 oprintf (base_files[fnum], "[];\n");
2440 size_t fnum;
2441 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2442 oprintf (base_files [fnum],
2443 "const struct %s * const %s[] = {\n",
2444 tname, name);
2448 for (fli2 = flp; fli2; fli2 = fli2->next)
2449 if (fli2->started_p)
2451 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2452 int fnum;
2454 fli2->started_p = 0;
2456 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2457 if (bitmap & 1)
2459 oprintf (base_files[fnum], " gt_%s_", pfx);
2460 put_mangled_filename (base_files[fnum], fli2->name);
2461 oprintf (base_files[fnum], ",\n");
2466 size_t fnum;
2467 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2469 oprintf (base_files[fnum], " NULL\n");
2470 oprintf (base_files[fnum], "};\n");
2475 /* Write out to F the table entry and any marker routines needed to
2476 mark NAME as TYPE. The original variable is V, at LINE.
2477 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2478 is nonzero iff we are building the root table for hash table caches. */
2480 static void
2481 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2482 struct fileloc *line, const char *if_marked)
2484 switch (type->kind)
2486 case TYPE_STRUCT:
2488 pair_p fld;
2489 for (fld = type->u.s.fields; fld; fld = fld->next)
2491 int skip_p = 0;
2492 const char *desc = NULL;
2493 options_p o;
2495 for (o = fld->opt; o; o = o->next)
2496 if (strcmp (o->name, "skip") == 0)
2497 skip_p = 1;
2498 else if (strcmp (o->name, "desc") == 0)
2499 desc = o->info;
2500 else
2501 error_at_line (line,
2502 "field `%s' of global `%s' has unknown option `%s'",
2503 fld->name, name, o->name);
2505 if (skip_p)
2506 continue;
2507 else if (desc && fld->type->kind == TYPE_UNION)
2509 pair_p validf = NULL;
2510 pair_p ufld;
2512 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2514 const char *tag = NULL;
2515 options_p oo;
2517 for (oo = ufld->opt; oo; oo = oo->next)
2518 if (strcmp (oo->name, "tag") == 0)
2519 tag = oo->info;
2520 if (tag == NULL || strcmp (tag, desc) != 0)
2521 continue;
2522 if (validf != NULL)
2523 error_at_line (line,
2524 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2525 name, fld->name, validf->name,
2526 name, fld->name, ufld->name,
2527 tag);
2528 validf = ufld;
2530 if (validf != NULL)
2532 char *newname;
2533 newname = xasprintf ("%s.%s.%s",
2534 name, fld->name, validf->name);
2535 write_root (f, v, validf->type, newname, 0, line,
2536 if_marked);
2537 free (newname);
2540 else if (desc)
2541 error_at_line (line,
2542 "global `%s.%s' has `desc' option but is not union",
2543 name, fld->name);
2544 else
2546 char *newname;
2547 newname = xasprintf ("%s.%s", name, fld->name);
2548 write_root (f, v, fld->type, newname, 0, line, if_marked);
2549 free (newname);
2553 break;
2555 case TYPE_ARRAY:
2557 char *newname;
2558 newname = xasprintf ("%s[0]", name);
2559 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2560 free (newname);
2562 break;
2564 case TYPE_POINTER:
2566 type_p ap, tp;
2568 oprintf (f, " {\n");
2569 oprintf (f, " &%s,\n", name);
2570 oprintf (f, " 1");
2572 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2573 if (ap->u.a.len[0])
2574 oprintf (f, " * (%s)", ap->u.a.len);
2575 else if (ap == v->type)
2576 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2577 oprintf (f, ",\n");
2578 oprintf (f, " sizeof (%s", v->name);
2579 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2580 oprintf (f, "[0]");
2581 oprintf (f, "),\n");
2583 tp = type->u.p;
2585 if (! has_length && UNION_OR_STRUCT_P (tp))
2587 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2588 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2590 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2592 oprintf (f, " &gt_ggc_m_");
2593 output_mangled_typename (f, tp);
2594 oprintf (f, ",\n &gt_pch_n_");
2595 output_mangled_typename (f, tp);
2597 else if (has_length
2598 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2600 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2601 oprintf (f, " &gt_pch_na_%s", name);
2603 else
2605 error_at_line (line,
2606 "global `%s' is pointer to unimplemented type",
2607 name);
2609 if (if_marked)
2610 oprintf (f, ",\n &%s", if_marked);
2611 oprintf (f, "\n },\n");
2613 break;
2615 case TYPE_STRING:
2617 oprintf (f, " {\n");
2618 oprintf (f, " &%s,\n", name);
2619 oprintf (f, " 1, \n");
2620 oprintf (f, " sizeof (%s),\n", v->name);
2621 oprintf (f, " &gt_ggc_m_S,\n");
2622 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2623 oprintf (f, " },\n");
2625 break;
2627 case TYPE_SCALAR:
2628 break;
2630 default:
2631 error_at_line (line,
2632 "global `%s' is unimplemented type",
2633 name);
2637 /* This generates a routine to walk an array. */
2639 static void
2640 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2642 struct walk_type_data d;
2643 char *prevval3;
2645 memset (&d, 0, sizeof (d));
2646 d.of = f;
2647 d.cookie = wtd;
2648 d.indent = 2;
2649 d.line = &v->line;
2650 d.opt = v->opt;
2651 d.bitmap = get_base_file_bitmap (v->line.file);
2652 d.param = NULL;
2654 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2656 if (wtd->param_prefix)
2658 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2659 oprintf (f,
2660 " (void *, void *, gt_pointer_operator, void *);\n");
2661 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2662 wtd->param_prefix, v->name);
2663 oprintf (d.of,
2664 " ATTRIBUTE_UNUSED void *x_p,\n"
2665 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2666 " ATTRIBUTE_UNUSED void * cookie)\n");
2667 oprintf (d.of, "{\n");
2668 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2669 d.process_field = write_types_local_process_field;
2670 walk_type (v->type, &d);
2671 oprintf (f, "}\n\n");
2674 d.opt = v->opt;
2675 oprintf (f, "static void gt_%sa_%s (void *);\n",
2676 wtd->prefix, v->name);
2677 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2678 wtd->prefix, v->name);
2679 oprintf (f, "{\n");
2680 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2681 d.process_field = write_types_process_field;
2682 walk_type (v->type, &d);
2683 free (prevval3);
2684 oprintf (f, "}\n\n");
2687 /* Output a table describing the locations and types of VARIABLES. */
2689 static void
2690 write_roots (pair_p variables)
2692 pair_p v;
2693 struct flist *flp = NULL;
2695 for (v = variables; v; v = v->next)
2697 outf_p f = get_output_file_with_visibility (v->line.file);
2698 struct flist *fli;
2699 const char *length = NULL;
2700 int deletable_p = 0;
2701 options_p o;
2703 for (o = v->opt; o; o = o->next)
2704 if (strcmp (o->name, "length") == 0)
2705 length = o->info;
2706 else if (strcmp (o->name, "deletable") == 0)
2707 deletable_p = 1;
2708 else if (strcmp (o->name, "param_is") == 0)
2710 else if (strncmp (o->name, "param", 5) == 0
2711 && ISDIGIT (o->name[5])
2712 && strcmp (o->name + 6, "_is") == 0)
2714 else if (strcmp (o->name, "if_marked") == 0)
2716 else
2717 error_at_line (&v->line,
2718 "global `%s' has unknown option `%s'",
2719 v->name, o->name);
2721 for (fli = flp; fli; fli = fli->next)
2722 if (fli->f == f)
2723 break;
2724 if (fli == NULL)
2726 fli = XNEW (struct flist);
2727 fli->f = f;
2728 fli->next = flp;
2729 fli->started_p = 0;
2730 fli->name = v->line.file;
2731 flp = fli;
2733 oprintf (f, "\n/* GC roots. */\n\n");
2736 if (! deletable_p
2737 && length
2738 && v->type->kind == TYPE_POINTER
2739 && (v->type->u.p->kind == TYPE_POINTER
2740 || v->type->u.p->kind == TYPE_STRUCT))
2742 write_array (f, v, &ggc_wtd);
2743 write_array (f, v, &pch_wtd);
2747 for (v = variables; v; v = v->next)
2749 outf_p f = get_output_file_with_visibility (v->line.file);
2750 struct flist *fli;
2751 int skip_p = 0;
2752 int length_p = 0;
2753 options_p o;
2755 for (o = v->opt; o; o = o->next)
2756 if (strcmp (o->name, "length") == 0)
2757 length_p = 1;
2758 else if (strcmp (o->name, "deletable") == 0
2759 || strcmp (o->name, "if_marked") == 0)
2760 skip_p = 1;
2762 if (skip_p)
2763 continue;
2765 for (fli = flp; fli; fli = fli->next)
2766 if (fli->f == f)
2767 break;
2768 if (! fli->started_p)
2770 fli->started_p = 1;
2772 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2773 put_mangled_filename (f, v->line.file);
2774 oprintf (f, "[] = {\n");
2777 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2780 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2781 "gt_ggc_rtab");
2783 for (v = variables; v; v = v->next)
2785 outf_p f = get_output_file_with_visibility (v->line.file);
2786 struct flist *fli;
2787 int skip_p = 1;
2788 options_p o;
2790 for (o = v->opt; o; o = o->next)
2791 if (strcmp (o->name, "deletable") == 0)
2792 skip_p = 0;
2793 else if (strcmp (o->name, "if_marked") == 0)
2794 skip_p = 1;
2796 if (skip_p)
2797 continue;
2799 for (fli = flp; fli; fli = fli->next)
2800 if (fli->f == f)
2801 break;
2802 if (! fli->started_p)
2804 fli->started_p = 1;
2806 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2807 put_mangled_filename (f, v->line.file);
2808 oprintf (f, "[] = {\n");
2811 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2812 v->name, v->name);
2815 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2816 "gt_ggc_deletable_rtab");
2818 for (v = variables; v; v = v->next)
2820 outf_p f = get_output_file_with_visibility (v->line.file);
2821 struct flist *fli;
2822 const char *if_marked = NULL;
2823 int length_p = 0;
2824 options_p o;
2826 for (o = v->opt; o; o = o->next)
2827 if (strcmp (o->name, "length") == 0)
2828 length_p = 1;
2829 else if (strcmp (o->name, "if_marked") == 0)
2830 if_marked = o->info;
2832 if (if_marked == NULL)
2833 continue;
2835 if (v->type->kind != TYPE_POINTER
2836 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2837 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2839 error_at_line (&v->line, "if_marked option used but not hash table");
2840 continue;
2843 for (fli = flp; fli; fli = fli->next)
2844 if (fli->f == f)
2845 break;
2846 if (! fli->started_p)
2848 fli->started_p = 1;
2850 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2851 put_mangled_filename (f, v->line.file);
2852 oprintf (f, "[] = {\n");
2855 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2856 v->name, length_p, &v->line, if_marked);
2859 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2860 "gt_ggc_cache_rtab");
2862 for (v = variables; v; v = v->next)
2864 outf_p f = get_output_file_with_visibility (v->line.file);
2865 struct flist *fli;
2866 int length_p = 0;
2867 int if_marked_p = 0;
2868 options_p o;
2870 for (o = v->opt; o; o = o->next)
2871 if (strcmp (o->name, "length") == 0)
2872 length_p = 1;
2873 else if (strcmp (o->name, "if_marked") == 0)
2874 if_marked_p = 1;
2876 if (! if_marked_p)
2877 continue;
2879 for (fli = flp; fli; fli = fli->next)
2880 if (fli->f == f)
2881 break;
2882 if (! fli->started_p)
2884 fli->started_p = 1;
2886 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2887 put_mangled_filename (f, v->line.file);
2888 oprintf (f, "[] = {\n");
2891 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2894 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2895 "gt_pch_cache_rtab");
2897 for (v = variables; v; v = v->next)
2899 outf_p f = get_output_file_with_visibility (v->line.file);
2900 struct flist *fli;
2901 int skip_p = 0;
2902 options_p o;
2904 for (o = v->opt; o; o = o->next)
2905 if (strcmp (o->name, "deletable") == 0
2906 || strcmp (o->name, "if_marked") == 0)
2907 skip_p = 1;
2909 if (skip_p)
2910 continue;
2912 if (! contains_scalar_p (v->type))
2913 continue;
2915 for (fli = flp; fli; fli = fli->next)
2916 if (fli->f == f)
2917 break;
2918 if (! fli->started_p)
2920 fli->started_p = 1;
2922 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2923 put_mangled_filename (f, v->line.file);
2924 oprintf (f, "[] = {\n");
2927 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2928 v->name, v->name);
2931 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2932 "gt_pch_scalar_rtab");
2936 extern int main (int argc, char **argv);
2938 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
2940 unsigned i;
2941 static struct fileloc pos = { __FILE__, __LINE__ };
2942 unsigned j;
2944 gen_rtx_next ();
2946 srcdir_len = strlen (srcdir);
2948 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
2949 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
2950 do_scalar_typedef ("uint8", &pos);
2951 do_scalar_typedef ("jword", &pos);
2952 do_scalar_typedef ("JCF_u2", &pos);
2953 #ifdef USE_MAPPED_LOCATION
2954 do_scalar_typedef ("location_t", &pos);
2955 do_scalar_typedef ("source_locus", &pos);
2956 #endif
2957 do_scalar_typedef ("void", &pos);
2959 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
2961 do_typedef ("HARD_REG_SET", create_array (
2962 create_scalar_type ("unsigned long", strlen ("unsigned long")),
2963 "2"), &pos);
2965 for (i = 0; i < NUM_GT_FILES; i++)
2967 int dupflag = 0;
2968 /* Omit if already seen. */
2969 for (j = 0; j < i; j++)
2971 if (!strcmp (all_files[i], all_files[j]))
2973 dupflag = 1;
2974 break;
2977 if (!dupflag)
2978 parse_file (all_files[i]);
2979 #ifndef USE_MAPPED_LOCATION
2980 /* temporary kludge - gengtype doesn't handle conditionals.
2981 Manually add source_locus *after* we've processed input.h. */
2982 if (i == 0)
2983 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
2984 #endif
2987 if (hit_error != 0)
2988 exit (1);
2990 set_gc_used (variables);
2992 open_base_files ();
2993 write_enum_defn (structures, param_structs);
2994 write_types (structures, param_structs, &ggc_wtd);
2995 write_types (structures, param_structs, &pch_wtd);
2996 write_local (structures, param_structs);
2997 write_roots (variables);
2998 write_rtx_next ();
2999 close_output_files ();
3001 return (hit_error != 0);