Ayee, missed a file.
[official-gcc.git] / gcc / gengtype.c
bloba1c23d2c9805b7812262e73f418d497d7c4d78bb
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 && !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 (slashpos)
1130 size_t i;
1131 for (i = 1; i < NUM_BASE_FILES; i++)
1132 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1133 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1135 /* It's in a language directory, set that language. */
1136 bitmap = 1 << i;
1137 return bitmap;
1140 abort (); /* Should have found the language. */
1143 /* If it's in any config-lang.in, then set for the languages
1144 specified. */
1146 bitmap = 0;
1148 for (j = 0; j < NUM_LANG_FILES; j++)
1150 if (!strcmp(input_file, lang_files[j]))
1152 for (k = 0; k < NUM_BASE_FILES; k++)
1154 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1155 bitmap |= (1 << k);
1160 /* Otherwise, set all languages. */
1161 if (!bitmap)
1162 bitmap = (1 << NUM_BASE_FILES) - 1;
1164 return bitmap;
1167 /* An output file, suitable for definitions, that can see declarations
1168 made in INPUT_FILE and is linked into every language that uses
1169 INPUT_FILE. */
1171 outf_p
1172 get_output_file_with_visibility (const char *input_file)
1174 outf_p r;
1175 size_t len;
1176 const char *basename;
1177 const char *for_name;
1178 const char *output_name;
1180 /* This can happen when we need a file with visibility on a
1181 structure that we've never seen. We have to just hope that it's
1182 globally visible. */
1183 if (input_file == NULL)
1184 input_file = "system.h";
1186 /* Determine the output file name. */
1187 basename = get_file_basename (input_file);
1189 len = strlen (basename);
1190 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1191 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1192 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1194 char *s;
1196 output_name = s = xasprintf ("gt-%s", basename);
1197 for (; *s != '.'; s++)
1198 if (! ISALNUM (*s) && *s != '-')
1199 *s = '-';
1200 memcpy (s, ".h", sizeof (".h"));
1201 for_name = basename;
1203 else if (strcmp (basename, "c-common.h") == 0)
1204 output_name = "gt-c-common.h", for_name = "c-common.c";
1205 else if (strcmp (basename, "c-tree.h") == 0)
1206 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1207 else
1209 size_t i;
1211 for (i = 0; i < NUM_BASE_FILES; i++)
1212 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1213 && basename[strlen(lang_dir_names[i])] == '/')
1214 return base_files[i];
1216 output_name = "gtype-desc.c";
1217 for_name = NULL;
1220 /* Look through to see if we've ever seen this output filename before. */
1221 for (r = output_files; r; r = r->next)
1222 if (strcmp (r->name, output_name) == 0)
1223 return r;
1225 /* If not, create it. */
1226 r = create_file (for_name, output_name);
1228 return r;
1231 /* The name of an output file, suitable for definitions, that can see
1232 declarations made in INPUT_FILE and is linked into every language
1233 that uses INPUT_FILE. */
1235 const char *
1236 get_output_file_name (const char *input_file)
1238 return get_output_file_with_visibility (input_file)->name;
1241 /* Copy the output to its final destination,
1242 but don't unnecessarily change modification times. */
1244 static void
1245 close_output_files (void)
1247 outf_p of;
1249 for (of = output_files; of; of = of->next)
1251 FILE * newfile;
1253 newfile = fopen (of->name, "r");
1254 if (newfile != NULL )
1256 int no_write_p;
1257 size_t i;
1259 for (i = 0; i < of->bufused; i++)
1261 int ch;
1262 ch = fgetc (newfile);
1263 if (ch == EOF || ch != (unsigned char) of->buf[i])
1264 break;
1266 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1267 fclose (newfile);
1269 if (no_write_p)
1270 continue;
1273 newfile = fopen (of->name, "w");
1274 if (newfile == NULL)
1276 perror ("opening output file");
1277 exit (1);
1279 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1281 perror ("writing output file");
1282 exit (1);
1284 if (fclose (newfile) != 0)
1286 perror ("closing output file");
1287 exit (1);
1292 struct flist {
1293 struct flist *next;
1294 int started_p;
1295 const char *name;
1296 outf_p f;
1299 struct walk_type_data;
1301 /* For scalars and strings, given the item in 'val'.
1302 For structures, given a pointer to the item in 'val'.
1303 For misc. pointers, given the item in 'val'.
1305 typedef void (*process_field_fn)
1306 (type_p f, const struct walk_type_data *p);
1307 typedef void (*func_name_fn)
1308 (type_p s, const struct walk_type_data *p);
1310 /* Parameters for write_types. */
1312 struct write_types_data
1314 const char *prefix;
1315 const char *param_prefix;
1316 const char *subfield_marker_routine;
1317 const char *marker_routine;
1318 const char *reorder_note_routine;
1319 const char *comment;
1322 static void output_escaped_param (struct walk_type_data *d,
1323 const char *, const char *);
1324 static void output_mangled_typename (outf_p, type_p);
1325 static void walk_type (type_p t, struct walk_type_data *d);
1326 static void write_func_for_structure
1327 (type_p orig_s, type_p s, type_p * param,
1328 const struct write_types_data *wtd);
1329 static void write_types_process_field
1330 (type_p f, const struct walk_type_data *d);
1331 static void write_types (type_p structures,
1332 type_p param_structs,
1333 const struct write_types_data *wtd);
1334 static void write_types_local_process_field
1335 (type_p f, const struct walk_type_data *d);
1336 static void write_local_func_for_structure
1337 (type_p orig_s, type_p s, type_p * param);
1338 static void write_local (type_p structures,
1339 type_p param_structs);
1340 static void write_enum_defn (type_p structures, type_p param_structs);
1341 static int contains_scalar_p (type_p t);
1342 static void put_mangled_filename (outf_p , const char *);
1343 static void finish_root_table (struct flist *flp, const char *pfx,
1344 const char *tname, const char *lastname,
1345 const char *name);
1346 static void write_root (outf_p , pair_p, type_p, const char *, int,
1347 struct fileloc *, const char *);
1348 static void write_array (outf_p f, pair_p v,
1349 const struct write_types_data *wtd);
1350 static void write_roots (pair_p);
1352 /* Parameters for walk_type. */
1354 struct walk_type_data
1356 process_field_fn process_field;
1357 const void *cookie;
1358 outf_p of;
1359 options_p opt;
1360 const char *val;
1361 const char *prev_val[4];
1362 int indent;
1363 int counter;
1364 struct fileloc *line;
1365 lang_bitmap bitmap;
1366 type_p *param;
1367 int used_length;
1368 type_p orig_s;
1369 const char *reorder_fn;
1370 bool needs_cast_p;
1371 bool fn_wants_lvalue;
1374 /* Print a mangled name representing T to OF. */
1376 static void
1377 output_mangled_typename (outf_p of, type_p t)
1379 if (t == NULL)
1380 oprintf (of, "Z");
1381 else switch (t->kind)
1383 case TYPE_POINTER:
1384 oprintf (of, "P");
1385 output_mangled_typename (of, t->u.p);
1386 break;
1387 case TYPE_SCALAR:
1388 oprintf (of, "I");
1389 break;
1390 case TYPE_STRING:
1391 oprintf (of, "S");
1392 break;
1393 case TYPE_STRUCT:
1394 case TYPE_UNION:
1395 case TYPE_LANG_STRUCT:
1396 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1397 break;
1398 case TYPE_PARAM_STRUCT:
1400 int i;
1401 for (i = 0; i < NUM_PARAM; i++)
1402 if (t->u.param_struct.param[i] != NULL)
1403 output_mangled_typename (of, t->u.param_struct.param[i]);
1404 output_mangled_typename (of, t->u.param_struct.stru);
1406 break;
1407 case TYPE_ARRAY:
1408 abort ();
1412 /* Print PARAM to D->OF processing escapes. D->VAL references the
1413 current object, D->PREV_VAL the object containing the current
1414 object, ONAME is the name of the option and D->LINE is used to
1415 print error messages. */
1417 static void
1418 output_escaped_param (struct walk_type_data *d, const char *param,
1419 const char *oname)
1421 const char *p;
1423 for (p = param; *p; p++)
1424 if (*p != '%')
1425 oprintf (d->of, "%c", *p);
1426 else switch (*++p)
1428 case 'h':
1429 oprintf (d->of, "(%s)", d->prev_val[2]);
1430 break;
1431 case '0':
1432 oprintf (d->of, "(%s)", d->prev_val[0]);
1433 break;
1434 case '1':
1435 oprintf (d->of, "(%s)", d->prev_val[1]);
1436 break;
1437 case 'a':
1439 const char *pp = d->val + strlen (d->val);
1440 while (pp[-1] == ']')
1441 while (*pp != '[')
1442 pp--;
1443 oprintf (d->of, "%s", pp);
1445 break;
1446 default:
1447 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1448 oname, '%', *p);
1452 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1453 which is of type T. Write code to D->OF to constrain execution (at
1454 the point that D->PROCESS_FIELD is called) to the appropriate
1455 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1456 pointers to those objects. D->PREV_VAL lists the objects
1457 containing the current object, D->OPT is a list of options to
1458 apply, D->INDENT is the current indentation level, D->LINE is used
1459 to print error messages, D->BITMAP indicates which languages to
1460 print the structure for, and D->PARAM is the current parameter
1461 (from an enclosing param_is option). */
1463 static void
1464 walk_type (type_p t, struct walk_type_data *d)
1466 const char *length = NULL;
1467 const char *desc = NULL;
1468 int maybe_undef_p = 0;
1469 int use_param_num = -1;
1470 int use_params_p = 0;
1471 options_p oo;
1472 const struct nested_ptr_data *nested_ptr_d = NULL;
1474 d->needs_cast_p = false;
1475 for (oo = d->opt; oo; oo = oo->next)
1476 if (strcmp (oo->name, "length") == 0)
1477 length = oo->info;
1478 else if (strcmp (oo->name, "maybe_undef") == 0)
1479 maybe_undef_p = 1;
1480 else if (strncmp (oo->name, "use_param", 9) == 0
1481 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1482 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1483 else if (strcmp (oo->name, "use_params") == 0)
1484 use_params_p = 1;
1485 else if (strcmp (oo->name, "desc") == 0)
1486 desc = oo->info;
1487 else if (strcmp (oo->name, "nested_ptr") == 0)
1488 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1489 else if (strcmp (oo->name, "dot") == 0)
1491 else if (strcmp (oo->name, "tag") == 0)
1493 else if (strcmp (oo->name, "special") == 0)
1495 else if (strcmp (oo->name, "skip") == 0)
1497 else if (strcmp (oo->name, "default") == 0)
1499 else if (strcmp (oo->name, "descbits") == 0)
1501 else if (strcmp (oo->name, "param_is") == 0)
1503 else if (strncmp (oo->name, "param", 5) == 0
1504 && ISDIGIT (oo->name[5])
1505 && strcmp (oo->name + 6, "_is") == 0)
1507 else if (strcmp (oo->name, "chain_next") == 0)
1509 else if (strcmp (oo->name, "chain_prev") == 0)
1511 else if (strcmp (oo->name, "reorder") == 0)
1513 else
1514 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1516 if (d->used_length)
1517 length = NULL;
1519 if (use_params_p)
1521 int pointer_p = t->kind == TYPE_POINTER;
1523 if (pointer_p)
1524 t = t->u.p;
1525 if (! UNION_OR_STRUCT_P (t))
1526 error_at_line (d->line, "`use_params' option on unimplemented type");
1527 else
1528 t = find_param_structure (t, d->param);
1529 if (pointer_p)
1530 t = create_pointer (t);
1533 if (use_param_num != -1)
1535 if (d->param != NULL && d->param[use_param_num] != NULL)
1537 type_p nt = d->param[use_param_num];
1539 if (t->kind == TYPE_ARRAY)
1540 nt = create_array (nt, t->u.a.len);
1541 else if (length != NULL && t->kind == TYPE_POINTER)
1542 nt = create_pointer (nt);
1543 d->needs_cast_p = (t->kind != TYPE_POINTER
1544 && (nt->kind == TYPE_POINTER
1545 || nt->kind == TYPE_STRING));
1546 t = nt;
1548 else
1549 error_at_line (d->line, "no parameter defined for `%s'",
1550 d->val);
1553 if (maybe_undef_p
1554 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1556 error_at_line (d->line,
1557 "field `%s' has invalid option `maybe_undef_p'\n",
1558 d->val);
1559 return;
1562 switch (t->kind)
1564 case TYPE_SCALAR:
1565 case TYPE_STRING:
1566 d->process_field (t, d);
1567 break;
1569 case TYPE_POINTER:
1571 if (maybe_undef_p
1572 && t->u.p->u.s.line.file == NULL)
1574 oprintf (d->of, "%*sif (%s) abort();\n", d->indent, "", d->val);
1575 break;
1578 if (! length)
1580 if (! UNION_OR_STRUCT_P (t->u.p)
1581 && t->u.p->kind != TYPE_PARAM_STRUCT)
1583 error_at_line (d->line,
1584 "field `%s' is pointer to unimplemented type",
1585 d->val);
1586 break;
1589 if (nested_ptr_d)
1591 const char *oldprevval2 = d->prev_val[2];
1593 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1595 error_at_line (d->line,
1596 "field `%s' has invalid "
1597 "option `nested_ptr'\n",
1598 d->val);
1599 return;
1602 d->prev_val[2] = d->val;
1603 oprintf (d->of, "%*s{\n", d->indent, "");
1604 d->indent += 2;
1605 d->val = xasprintf ("x%d", d->counter++);
1606 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1607 (nested_ptr_d->type->kind == TYPE_UNION
1608 ? "union" : "struct"),
1609 nested_ptr_d->type->u.s.tag,
1610 d->fn_wants_lvalue ? "" : "const ",
1611 d->val);
1612 oprintf (d->of, "%*s", d->indent + 2, "");
1613 output_escaped_param (d, nested_ptr_d->convert_from,
1614 "nested_ptr");
1615 oprintf (d->of, ";\n");
1617 d->process_field (nested_ptr_d->type, d);
1619 if (d->fn_wants_lvalue)
1621 oprintf (d->of, "%*s%s = ", d->indent, "",
1622 d->prev_val[2]);
1623 d->prev_val[2] = d->val;
1624 output_escaped_param (d, nested_ptr_d->convert_to,
1625 "nested_ptr");
1626 oprintf (d->of, ";\n");
1629 d->indent -= 2;
1630 oprintf (d->of, "%*s}\n", d->indent, "");
1631 d->val = d->prev_val[2];
1632 d->prev_val[2] = oldprevval2;
1634 else
1635 d->process_field (t->u.p, d);
1637 else
1639 int loopcounter = d->counter++;
1640 const char *oldval = d->val;
1641 const char *oldprevval3 = d->prev_val[3];
1642 char *newval;
1644 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1645 d->indent += 2;
1646 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1647 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1648 loopcounter, loopcounter);
1649 output_escaped_param (d, length, "length");
1650 oprintf (d->of, "); i%d++) {\n", loopcounter);
1651 d->indent += 2;
1652 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1653 d->used_length = 1;
1654 d->prev_val[3] = oldval;
1655 walk_type (t->u.p, d);
1656 free (newval);
1657 d->val = oldval;
1658 d->prev_val[3] = oldprevval3;
1659 d->used_length = 0;
1660 d->indent -= 2;
1661 oprintf (d->of, "%*s}\n", d->indent, "");
1662 d->process_field(t, d);
1663 d->indent -= 2;
1664 oprintf (d->of, "%*s}\n", d->indent, "");
1667 break;
1669 case TYPE_ARRAY:
1671 int loopcounter = d->counter++;
1672 const char *oldval = d->val;
1673 char *newval;
1675 /* If it's an array of scalars, we optimize by not generating
1676 any code. */
1677 if (t->u.a.p->kind == TYPE_SCALAR)
1678 break;
1680 oprintf (d->of, "%*s{\n", d->indent, "");
1681 d->indent += 2;
1682 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1683 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1684 loopcounter, loopcounter);
1685 if (length)
1686 output_escaped_param (d, length, "length");
1687 else
1688 oprintf (d->of, "%s", t->u.a.len);
1689 oprintf (d->of, "); i%d++) {\n", loopcounter);
1690 d->indent += 2;
1691 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1692 d->used_length = 1;
1693 walk_type (t->u.a.p, d);
1694 free (newval);
1695 d->used_length = 0;
1696 d->val = oldval;
1697 d->indent -= 2;
1698 oprintf (d->of, "%*s}\n", d->indent, "");
1699 d->indent -= 2;
1700 oprintf (d->of, "%*s}\n", d->indent, "");
1702 break;
1704 case TYPE_STRUCT:
1705 case TYPE_UNION:
1707 pair_p f;
1708 const char *oldval = d->val;
1709 const char *oldprevval1 = d->prev_val[1];
1710 const char *oldprevval2 = d->prev_val[2];
1711 const int union_p = t->kind == TYPE_UNION;
1712 int seen_default_p = 0;
1713 options_p o;
1715 if (! t->u.s.line.file)
1716 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1718 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1720 error_at_line (d->line,
1721 "structure `%s' defined for mismatching languages",
1722 t->u.s.tag);
1723 error_at_line (&t->u.s.line, "one structure defined here");
1726 /* Some things may also be defined in the structure's options. */
1727 for (o = t->u.s.opt; o; o = o->next)
1728 if (! desc && strcmp (o->name, "desc") == 0)
1729 desc = o->info;
1731 d->prev_val[2] = oldval;
1732 d->prev_val[1] = oldprevval2;
1733 if (union_p)
1735 if (desc == NULL)
1737 error_at_line (d->line, "missing `desc' option for union `%s'",
1738 t->u.s.tag);
1739 desc = "1";
1741 oprintf (d->of, "%*sswitch (", d->indent, "");
1742 output_escaped_param (d, desc, "desc");
1743 oprintf (d->of, ")\n");
1744 d->indent += 2;
1745 oprintf (d->of, "%*s{\n", d->indent, "");
1747 for (f = t->u.s.fields; f; f = f->next)
1749 options_p oo;
1750 const char *dot = ".";
1751 const char *tagid = NULL;
1752 int skip_p = 0;
1753 int default_p = 0;
1754 int use_param_p = 0;
1755 char *newval;
1757 d->reorder_fn = NULL;
1758 for (oo = f->opt; oo; oo = oo->next)
1759 if (strcmp (oo->name, "dot") == 0)
1760 dot = oo->info;
1761 else if (strcmp (oo->name, "tag") == 0)
1762 tagid = oo->info;
1763 else if (strcmp (oo->name, "skip") == 0)
1764 skip_p = 1;
1765 else if (strcmp (oo->name, "default") == 0)
1766 default_p = 1;
1767 else if (strcmp (oo->name, "reorder") == 0)
1768 d->reorder_fn = oo->info;
1769 else if (strncmp (oo->name, "use_param", 9) == 0
1770 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1771 use_param_p = 1;
1773 if (skip_p)
1774 continue;
1776 if (union_p && tagid)
1778 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1779 d->indent += 2;
1781 else if (union_p && default_p)
1783 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1784 d->indent += 2;
1785 seen_default_p = 1;
1787 else if (! union_p && (default_p || tagid))
1788 error_at_line (d->line,
1789 "can't use `%s' outside a union on field `%s'",
1790 default_p ? "default" : "tag", f->name);
1791 else if (union_p && ! (default_p || tagid)
1792 && f->type->kind == TYPE_SCALAR)
1794 fprintf (stderr,
1795 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1796 d->line->file, d->line->line, f->name);
1797 continue;
1799 else if (union_p && ! (default_p || tagid))
1800 error_at_line (d->line,
1801 "field `%s' is missing `tag' or `default' option",
1802 f->name);
1804 d->line = &f->line;
1805 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1806 d->opt = f->opt;
1807 d->used_length = false;
1809 if (union_p && use_param_p && d->param == NULL)
1810 oprintf (d->of, "%*sabort();\n", d->indent, "");
1811 else
1812 walk_type (f->type, d);
1814 free (newval);
1816 if (union_p)
1818 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1819 d->indent -= 2;
1822 d->reorder_fn = NULL;
1824 d->val = oldval;
1825 d->prev_val[1] = oldprevval1;
1826 d->prev_val[2] = oldprevval2;
1828 if (union_p && ! seen_default_p)
1830 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1831 oprintf (d->of, "%*s break;\n", d->indent, "");
1833 if (union_p)
1835 oprintf (d->of, "%*s}\n", d->indent, "");
1836 d->indent -= 2;
1839 break;
1841 case TYPE_LANG_STRUCT:
1843 type_p nt;
1844 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1845 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1846 break;
1847 if (nt == NULL)
1848 error_at_line (d->line, "structure `%s' differs between languages",
1849 t->u.s.tag);
1850 else
1851 walk_type (nt, d);
1853 break;
1855 case TYPE_PARAM_STRUCT:
1857 type_p *oldparam = d->param;
1859 d->param = t->u.param_struct.param;
1860 walk_type (t->u.param_struct.stru, d);
1861 d->param = oldparam;
1863 break;
1865 default:
1866 abort ();
1870 /* process_field routine for marking routines. */
1872 static void
1873 write_types_process_field (type_p f, const struct walk_type_data *d)
1875 const struct write_types_data *wtd;
1876 const char *cast = d->needs_cast_p ? "(void *)" : "";
1877 wtd = (const struct write_types_data *) d->cookie;
1879 switch (f->kind)
1881 case TYPE_POINTER:
1882 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1883 wtd->subfield_marker_routine, cast, d->val);
1884 if (wtd->param_prefix)
1886 oprintf (d->of, ", %s", d->prev_val[3]);
1887 if (d->orig_s)
1889 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1890 output_mangled_typename (d->of, d->orig_s);
1892 else
1893 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1895 oprintf (d->of, ");\n");
1896 if (d->reorder_fn && wtd->reorder_note_routine)
1897 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1898 wtd->reorder_note_routine, cast, d->val,
1899 d->prev_val[3], d->reorder_fn);
1900 break;
1902 case TYPE_STRING:
1903 if (wtd->param_prefix == NULL)
1904 break;
1906 case TYPE_STRUCT:
1907 case TYPE_UNION:
1908 case TYPE_LANG_STRUCT:
1909 case TYPE_PARAM_STRUCT:
1910 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1911 output_mangled_typename (d->of, f);
1912 oprintf (d->of, " (%s%s);\n", cast, d->val);
1913 if (d->reorder_fn && wtd->reorder_note_routine)
1914 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1915 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1916 d->reorder_fn);
1917 break;
1919 case TYPE_SCALAR:
1920 break;
1922 default:
1923 abort ();
1927 /* For S, a structure that's part of ORIG_S, and using parameters
1928 PARAM, write out a routine that:
1929 - Takes a parameter, a void * but actually of type *S
1930 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1931 field of S or its substructures and (in some cases) things
1932 that are pointed to by S.
1935 static void
1936 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
1937 const struct write_types_data *wtd)
1939 const char *fn = s->u.s.line.file;
1940 int i;
1941 const char *chain_next = NULL;
1942 const char *chain_prev = NULL;
1943 options_p opt;
1944 struct walk_type_data d;
1946 /* This is a hack, and not the good kind either. */
1947 for (i = NUM_PARAM - 1; i >= 0; i--)
1948 if (param && param[i] && param[i]->kind == TYPE_POINTER
1949 && UNION_OR_STRUCT_P (param[i]->u.p))
1950 fn = param[i]->u.p->u.s.line.file;
1952 memset (&d, 0, sizeof (d));
1953 d.of = get_output_file_with_visibility (fn);
1955 for (opt = s->u.s.opt; opt; opt = opt->next)
1956 if (strcmp (opt->name, "chain_next") == 0)
1957 chain_next = opt->info;
1958 else if (strcmp (opt->name, "chain_prev") == 0)
1959 chain_prev = opt->info;
1961 if (chain_prev != NULL && chain_next == NULL)
1962 error_at_line (&s->u.s.line, "chain_prev without chain_next");
1964 d.process_field = write_types_process_field;
1965 d.cookie = wtd;
1966 d.orig_s = orig_s;
1967 d.opt = s->u.s.opt;
1968 d.line = &s->u.s.line;
1969 d.bitmap = s->u.s.bitmap;
1970 d.param = param;
1971 d.prev_val[0] = "*x";
1972 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
1973 d.prev_val[3] = "x";
1974 d.val = "(*x)";
1976 oprintf (d.of, "\n");
1977 oprintf (d.of, "void\n");
1978 if (param == NULL)
1979 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
1980 else
1982 oprintf (d.of, "gt_%s_", wtd->prefix);
1983 output_mangled_typename (d.of, orig_s);
1985 oprintf (d.of, " (void *x_p)\n");
1986 oprintf (d.of, "{\n");
1987 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
1988 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1989 chain_next == NULL ? "const " : "",
1990 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1991 if (chain_next != NULL)
1992 oprintf (d.of, " %s %s * xlimit = x;\n",
1993 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1994 if (chain_next == NULL)
1996 oprintf (d.of, " if (%s (x", wtd->marker_routine);
1997 if (wtd->param_prefix)
1999 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2000 output_mangled_typename (d.of, orig_s);
2002 oprintf (d.of, "))\n");
2004 else
2006 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2007 if (wtd->param_prefix)
2009 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2010 output_mangled_typename (d.of, orig_s);
2012 oprintf (d.of, "))\n");
2013 oprintf (d.of, " xlimit = (");
2014 d.prev_val[2] = "*xlimit";
2015 output_escaped_param (&d, chain_next, "chain_next");
2016 oprintf (d.of, ");\n");
2017 if (chain_prev != NULL)
2019 oprintf (d.of, " if (x != xlimit)\n");
2020 oprintf (d.of, " for (;;)\n");
2021 oprintf (d.of, " {\n");
2022 oprintf (d.of, " %s %s * const xprev = (",
2023 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2025 d.prev_val[2] = "*x";
2026 output_escaped_param (&d, chain_prev, "chain_prev");
2027 oprintf (d.of, ");\n");
2028 oprintf (d.of, " if (xprev == NULL) break;\n");
2029 oprintf (d.of, " x = xprev;\n");
2030 oprintf (d.of, " (void) %s (xprev",
2031 wtd->marker_routine);
2032 if (wtd->param_prefix)
2034 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2035 output_mangled_typename (d.of, orig_s);
2037 oprintf (d.of, ");\n");
2038 oprintf (d.of, " }\n");
2040 oprintf (d.of, " while (x != xlimit)\n");
2042 oprintf (d.of, " {\n");
2044 d.prev_val[2] = "*x";
2045 d.indent = 6;
2046 walk_type (s, &d);
2048 if (chain_next != NULL)
2050 oprintf (d.of, " x = (");
2051 output_escaped_param (&d, chain_next, "chain_next");
2052 oprintf (d.of, ");\n");
2055 oprintf (d.of, " }\n");
2056 oprintf (d.of, "}\n");
2059 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2061 static void
2062 write_types (type_p structures, type_p param_structs,
2063 const struct write_types_data *wtd)
2065 type_p s;
2067 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2068 for (s = structures; s; s = s->next)
2069 if (s->gc_used == GC_POINTED_TO
2070 || s->gc_used == GC_MAYBE_POINTED_TO)
2072 options_p opt;
2074 if (s->gc_used == GC_MAYBE_POINTED_TO
2075 && s->u.s.line.file == NULL)
2076 continue;
2078 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2079 output_mangled_typename (header_file, s);
2080 oprintf (header_file, "(X) do { \\\n");
2081 oprintf (header_file,
2082 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2083 s->u.s.tag);
2084 oprintf (header_file,
2085 " } while (0)\n");
2087 for (opt = s->u.s.opt; opt; opt = opt->next)
2088 if (strcmp (opt->name, "ptr_alias") == 0)
2090 type_p t = (type_p) opt->info;
2091 if (t->kind == TYPE_STRUCT
2092 || t->kind == TYPE_UNION
2093 || t->kind == TYPE_LANG_STRUCT)
2094 oprintf (header_file,
2095 "#define gt_%sx_%s gt_%sx_%s\n",
2096 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2097 else
2098 error_at_line (&s->u.s.line,
2099 "structure alias is not a structure");
2100 break;
2102 if (opt)
2103 continue;
2105 /* Declare the marker procedure only once. */
2106 oprintf (header_file,
2107 "extern void gt_%sx_%s (void *);\n",
2108 wtd->prefix, s->u.s.tag);
2110 if (s->u.s.line.file == NULL)
2112 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2113 s->u.s.tag);
2114 continue;
2117 if (s->kind == TYPE_LANG_STRUCT)
2119 type_p ss;
2120 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2121 write_func_for_structure (s, ss, NULL, wtd);
2123 else
2124 write_func_for_structure (s, s, NULL, wtd);
2127 for (s = param_structs; s; s = s->next)
2128 if (s->gc_used == GC_POINTED_TO)
2130 type_p * param = s->u.param_struct.param;
2131 type_p stru = s->u.param_struct.stru;
2133 /* Declare the marker procedure. */
2134 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2135 output_mangled_typename (header_file, s);
2136 oprintf (header_file, " (void *);\n");
2138 if (stru->u.s.line.file == NULL)
2140 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2141 s->u.s.tag);
2142 continue;
2145 if (stru->kind == TYPE_LANG_STRUCT)
2147 type_p ss;
2148 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2149 write_func_for_structure (s, ss, param, wtd);
2151 else
2152 write_func_for_structure (s, stru, param, wtd);
2156 static const struct write_types_data ggc_wtd =
2158 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2159 "GC marker procedures. "
2162 static const struct write_types_data pch_wtd =
2164 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2165 "gt_pch_note_reorder",
2166 "PCH type-walking procedures. "
2169 /* Write out the local pointer-walking routines. */
2171 /* process_field routine for local pointer-walking. */
2173 static void
2174 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2176 switch (f->kind)
2178 case TYPE_POINTER:
2179 case TYPE_STRUCT:
2180 case TYPE_UNION:
2181 case TYPE_LANG_STRUCT:
2182 case TYPE_PARAM_STRUCT:
2183 case TYPE_STRING:
2184 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2185 d->prev_val[3]);
2186 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2187 break;
2189 case TYPE_SCALAR:
2190 break;
2192 default:
2193 abort ();
2197 /* For S, a structure that's part of ORIG_S, and using parameters
2198 PARAM, write out a routine that:
2199 - Is of type gt_note_pointers
2200 - Calls PROCESS_FIELD on each field of S or its substructures.
2203 static void
2204 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2206 const char *fn = s->u.s.line.file;
2207 int i;
2208 struct walk_type_data d;
2210 /* This is a hack, and not the good kind either. */
2211 for (i = NUM_PARAM - 1; i >= 0; i--)
2212 if (param && param[i] && param[i]->kind == TYPE_POINTER
2213 && UNION_OR_STRUCT_P (param[i]->u.p))
2214 fn = param[i]->u.p->u.s.line.file;
2216 memset (&d, 0, sizeof (d));
2217 d.of = get_output_file_with_visibility (fn);
2219 d.process_field = write_types_local_process_field;
2220 d.opt = s->u.s.opt;
2221 d.line = &s->u.s.line;
2222 d.bitmap = s->u.s.bitmap;
2223 d.param = param;
2224 d.prev_val[0] = d.prev_val[2] = "*x";
2225 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2226 d.prev_val[3] = "x";
2227 d.val = "(*x)";
2228 d.fn_wants_lvalue = true;
2230 oprintf (d.of, "\n");
2231 oprintf (d.of, "void\n");
2232 oprintf (d.of, "gt_pch_p_");
2233 output_mangled_typename (d.of, orig_s);
2234 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2235 "\tvoid *x_p,\n"
2236 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2237 "\tATTRIBUTE_UNUSED void *cookie)\n");
2238 oprintf (d.of, "{\n");
2239 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2240 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2241 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2242 d.indent = 2;
2243 walk_type (s, &d);
2244 oprintf (d.of, "}\n");
2247 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2249 static void
2250 write_local (type_p structures, type_p param_structs)
2252 type_p s;
2254 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2255 for (s = structures; s; s = s->next)
2256 if (s->gc_used == GC_POINTED_TO
2257 || s->gc_used == GC_MAYBE_POINTED_TO)
2259 options_p opt;
2261 if (s->u.s.line.file == NULL)
2262 continue;
2264 for (opt = s->u.s.opt; opt; opt = opt->next)
2265 if (strcmp (opt->name, "ptr_alias") == 0)
2267 type_p t = (type_p) opt->info;
2268 if (t->kind == TYPE_STRUCT
2269 || t->kind == TYPE_UNION
2270 || t->kind == TYPE_LANG_STRUCT)
2272 oprintf (header_file, "#define gt_pch_p_");
2273 output_mangled_typename (header_file, s);
2274 oprintf (header_file, " gt_pch_p_");
2275 output_mangled_typename (header_file, t);
2276 oprintf (header_file, "\n");
2278 else
2279 error_at_line (&s->u.s.line,
2280 "structure alias is not a structure");
2281 break;
2283 if (opt)
2284 continue;
2286 /* Declare the marker procedure only once. */
2287 oprintf (header_file, "extern void gt_pch_p_");
2288 output_mangled_typename (header_file, s);
2289 oprintf (header_file,
2290 "\n (void *, void *, gt_pointer_operator, void *);\n");
2292 if (s->kind == TYPE_LANG_STRUCT)
2294 type_p ss;
2295 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2296 write_local_func_for_structure (s, ss, NULL);
2298 else
2299 write_local_func_for_structure (s, s, NULL);
2302 for (s = param_structs; s; s = s->next)
2303 if (s->gc_used == GC_POINTED_TO)
2305 type_p * param = s->u.param_struct.param;
2306 type_p stru = s->u.param_struct.stru;
2308 /* Declare the marker procedure. */
2309 oprintf (header_file, "extern void gt_pch_p_");
2310 output_mangled_typename (header_file, s);
2311 oprintf (header_file,
2312 "\n (void *, void *, gt_pointer_operator, void *);\n");
2314 if (stru->u.s.line.file == NULL)
2316 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2317 s->u.s.tag);
2318 continue;
2321 if (stru->kind == TYPE_LANG_STRUCT)
2323 type_p ss;
2324 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2325 write_local_func_for_structure (s, ss, param);
2327 else
2328 write_local_func_for_structure (s, stru, param);
2332 /* Write out the 'enum' definition for gt_types_enum. */
2334 static void
2335 write_enum_defn (type_p structures, type_p param_structs)
2337 type_p s;
2339 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2340 oprintf (header_file, "enum gt_types_enum {\n");
2341 for (s = structures; s; s = s->next)
2342 if (s->gc_used == GC_POINTED_TO
2343 || s->gc_used == GC_MAYBE_POINTED_TO)
2345 if (s->gc_used == GC_MAYBE_POINTED_TO
2346 && s->u.s.line.file == NULL)
2347 continue;
2349 oprintf (header_file, " gt_ggc_e_");
2350 output_mangled_typename (header_file, s);
2351 oprintf (header_file, ", \n");
2353 for (s = param_structs; s; s = s->next)
2354 if (s->gc_used == GC_POINTED_TO)
2356 oprintf (header_file, " gt_e_");
2357 output_mangled_typename (header_file, s);
2358 oprintf (header_file, ", \n");
2360 oprintf (header_file, " gt_types_enum_last\n");
2361 oprintf (header_file, "};\n");
2364 /* Might T contain any non-pointer elements? */
2366 static int
2367 contains_scalar_p (type_p t)
2369 switch (t->kind)
2371 case TYPE_STRING:
2372 case TYPE_POINTER:
2373 return 0;
2374 case TYPE_ARRAY:
2375 return contains_scalar_p (t->u.a.p);
2376 default:
2377 /* Could also check for structures that have no non-pointer
2378 fields, but there aren't enough of those to worry about. */
2379 return 1;
2383 /* Mangle FN and print it to F. */
2385 static void
2386 put_mangled_filename (outf_p f, const char *fn)
2388 const char *name = get_output_file_name (fn);
2389 for (; *name != 0; name++)
2390 if (ISALNUM (*name))
2391 oprintf (f, "%c", *name);
2392 else
2393 oprintf (f, "%c", '_');
2396 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2397 LASTNAME, and NAME are all strings to insert in various places in
2398 the resulting code. */
2400 static void
2401 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2402 const char *tname, const char *name)
2404 struct flist *fli2;
2406 for (fli2 = flp; fli2; fli2 = fli2->next)
2407 if (fli2->started_p)
2409 oprintf (fli2->f, " %s\n", lastname);
2410 oprintf (fli2->f, "};\n\n");
2413 for (fli2 = flp; fli2; fli2 = fli2->next)
2414 if (fli2->started_p)
2416 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2417 int fnum;
2419 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2420 if (bitmap & 1)
2422 oprintf (base_files[fnum],
2423 "extern const struct %s gt_%s_",
2424 tname, pfx);
2425 put_mangled_filename (base_files[fnum], fli2->name);
2426 oprintf (base_files[fnum], "[];\n");
2431 size_t fnum;
2432 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2433 oprintf (base_files [fnum],
2434 "const struct %s * const %s[] = {\n",
2435 tname, name);
2439 for (fli2 = flp; fli2; fli2 = fli2->next)
2440 if (fli2->started_p)
2442 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2443 int fnum;
2445 fli2->started_p = 0;
2447 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2448 if (bitmap & 1)
2450 oprintf (base_files[fnum], " gt_%s_", pfx);
2451 put_mangled_filename (base_files[fnum], fli2->name);
2452 oprintf (base_files[fnum], ",\n");
2457 size_t fnum;
2458 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2460 oprintf (base_files[fnum], " NULL\n");
2461 oprintf (base_files[fnum], "};\n");
2466 /* Write out to F the table entry and any marker routines needed to
2467 mark NAME as TYPE. The original variable is V, at LINE.
2468 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2469 is nonzero iff we are building the root table for hash table caches. */
2471 static void
2472 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2473 struct fileloc *line, const char *if_marked)
2475 switch (type->kind)
2477 case TYPE_STRUCT:
2479 pair_p fld;
2480 for (fld = type->u.s.fields; fld; fld = fld->next)
2482 int skip_p = 0;
2483 const char *desc = NULL;
2484 options_p o;
2486 for (o = fld->opt; o; o = o->next)
2487 if (strcmp (o->name, "skip") == 0)
2488 skip_p = 1;
2489 else if (strcmp (o->name, "desc") == 0)
2490 desc = o->info;
2491 else
2492 error_at_line (line,
2493 "field `%s' of global `%s' has unknown option `%s'",
2494 fld->name, name, o->name);
2496 if (skip_p)
2497 continue;
2498 else if (desc && fld->type->kind == TYPE_UNION)
2500 pair_p validf = NULL;
2501 pair_p ufld;
2503 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2505 const char *tag = NULL;
2506 options_p oo;
2508 for (oo = ufld->opt; oo; oo = oo->next)
2509 if (strcmp (oo->name, "tag") == 0)
2510 tag = oo->info;
2511 if (tag == NULL || strcmp (tag, desc) != 0)
2512 continue;
2513 if (validf != NULL)
2514 error_at_line (line,
2515 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2516 name, fld->name, validf->name,
2517 name, fld->name, ufld->name,
2518 tag);
2519 validf = ufld;
2521 if (validf != NULL)
2523 char *newname;
2524 newname = xasprintf ("%s.%s.%s",
2525 name, fld->name, validf->name);
2526 write_root (f, v, validf->type, newname, 0, line,
2527 if_marked);
2528 free (newname);
2531 else if (desc)
2532 error_at_line (line,
2533 "global `%s.%s' has `desc' option but is not union",
2534 name, fld->name);
2535 else
2537 char *newname;
2538 newname = xasprintf ("%s.%s", name, fld->name);
2539 write_root (f, v, fld->type, newname, 0, line, if_marked);
2540 free (newname);
2544 break;
2546 case TYPE_ARRAY:
2548 char *newname;
2549 newname = xasprintf ("%s[0]", name);
2550 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2551 free (newname);
2553 break;
2555 case TYPE_POINTER:
2557 type_p ap, tp;
2559 oprintf (f, " {\n");
2560 oprintf (f, " &%s,\n", name);
2561 oprintf (f, " 1");
2563 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2564 if (ap->u.a.len[0])
2565 oprintf (f, " * (%s)", ap->u.a.len);
2566 else if (ap == v->type)
2567 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2568 oprintf (f, ",\n");
2569 oprintf (f, " sizeof (%s", v->name);
2570 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2571 oprintf (f, "[0]");
2572 oprintf (f, "),\n");
2574 tp = type->u.p;
2576 if (! has_length && UNION_OR_STRUCT_P (tp))
2578 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2579 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2581 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2583 oprintf (f, " &gt_ggc_m_");
2584 output_mangled_typename (f, tp);
2585 oprintf (f, ",\n &gt_pch_n_");
2586 output_mangled_typename (f, tp);
2588 else if (has_length
2589 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2591 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2592 oprintf (f, " &gt_pch_na_%s", name);
2594 else
2596 error_at_line (line,
2597 "global `%s' is pointer to unimplemented type",
2598 name);
2600 if (if_marked)
2601 oprintf (f, ",\n &%s", if_marked);
2602 oprintf (f, "\n },\n");
2604 break;
2606 case TYPE_STRING:
2608 oprintf (f, " {\n");
2609 oprintf (f, " &%s,\n", name);
2610 oprintf (f, " 1, \n");
2611 oprintf (f, " sizeof (%s),\n", v->name);
2612 oprintf (f, " &gt_ggc_m_S,\n");
2613 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2614 oprintf (f, " },\n");
2616 break;
2618 case TYPE_SCALAR:
2619 break;
2621 default:
2622 error_at_line (line,
2623 "global `%s' is unimplemented type",
2624 name);
2628 /* This generates a routine to walk an array. */
2630 static void
2631 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2633 struct walk_type_data d;
2634 char *prevval3;
2636 memset (&d, 0, sizeof (d));
2637 d.of = f;
2638 d.cookie = wtd;
2639 d.indent = 2;
2640 d.line = &v->line;
2641 d.opt = v->opt;
2642 d.bitmap = get_base_file_bitmap (v->line.file);
2643 d.param = NULL;
2645 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2647 if (wtd->param_prefix)
2649 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2650 oprintf (f,
2651 " (void *, void *, gt_pointer_operator, void *);\n");
2652 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2653 wtd->param_prefix, v->name);
2654 oprintf (d.of,
2655 " ATTRIBUTE_UNUSED void *x_p,\n"
2656 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2657 " ATTRIBUTE_UNUSED void * cookie)\n");
2658 oprintf (d.of, "{\n");
2659 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2660 d.process_field = write_types_local_process_field;
2661 walk_type (v->type, &d);
2662 oprintf (f, "}\n\n");
2665 d.opt = v->opt;
2666 oprintf (f, "static void gt_%sa_%s (void *);\n",
2667 wtd->prefix, v->name);
2668 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2669 wtd->prefix, v->name);
2670 oprintf (f, "{\n");
2671 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2672 d.process_field = write_types_process_field;
2673 walk_type (v->type, &d);
2674 free (prevval3);
2675 oprintf (f, "}\n\n");
2678 /* Output a table describing the locations and types of VARIABLES. */
2680 static void
2681 write_roots (pair_p variables)
2683 pair_p v;
2684 struct flist *flp = NULL;
2686 for (v = variables; v; v = v->next)
2688 outf_p f = get_output_file_with_visibility (v->line.file);
2689 struct flist *fli;
2690 const char *length = NULL;
2691 int deletable_p = 0;
2692 options_p o;
2694 for (o = v->opt; o; o = o->next)
2695 if (strcmp (o->name, "length") == 0)
2696 length = o->info;
2697 else if (strcmp (o->name, "deletable") == 0)
2698 deletable_p = 1;
2699 else if (strcmp (o->name, "param_is") == 0)
2701 else if (strncmp (o->name, "param", 5) == 0
2702 && ISDIGIT (o->name[5])
2703 && strcmp (o->name + 6, "_is") == 0)
2705 else if (strcmp (o->name, "if_marked") == 0)
2707 else
2708 error_at_line (&v->line,
2709 "global `%s' has unknown option `%s'",
2710 v->name, o->name);
2712 for (fli = flp; fli; fli = fli->next)
2713 if (fli->f == f)
2714 break;
2715 if (fli == NULL)
2717 fli = XNEW (struct flist);
2718 fli->f = f;
2719 fli->next = flp;
2720 fli->started_p = 0;
2721 fli->name = v->line.file;
2722 flp = fli;
2724 oprintf (f, "\n/* GC roots. */\n\n");
2727 if (! deletable_p
2728 && length
2729 && v->type->kind == TYPE_POINTER
2730 && (v->type->u.p->kind == TYPE_POINTER
2731 || v->type->u.p->kind == TYPE_STRUCT))
2733 write_array (f, v, &ggc_wtd);
2734 write_array (f, v, &pch_wtd);
2738 for (v = variables; v; v = v->next)
2740 outf_p f = get_output_file_with_visibility (v->line.file);
2741 struct flist *fli;
2742 int skip_p = 0;
2743 int length_p = 0;
2744 options_p o;
2746 for (o = v->opt; o; o = o->next)
2747 if (strcmp (o->name, "length") == 0)
2748 length_p = 1;
2749 else if (strcmp (o->name, "deletable") == 0
2750 || strcmp (o->name, "if_marked") == 0)
2751 skip_p = 1;
2753 if (skip_p)
2754 continue;
2756 for (fli = flp; fli; fli = fli->next)
2757 if (fli->f == f)
2758 break;
2759 if (! fli->started_p)
2761 fli->started_p = 1;
2763 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2764 put_mangled_filename (f, v->line.file);
2765 oprintf (f, "[] = {\n");
2768 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2771 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2772 "gt_ggc_rtab");
2774 for (v = variables; v; v = v->next)
2776 outf_p f = get_output_file_with_visibility (v->line.file);
2777 struct flist *fli;
2778 int skip_p = 1;
2779 options_p o;
2781 for (o = v->opt; o; o = o->next)
2782 if (strcmp (o->name, "deletable") == 0)
2783 skip_p = 0;
2784 else if (strcmp (o->name, "if_marked") == 0)
2785 skip_p = 1;
2787 if (skip_p)
2788 continue;
2790 for (fli = flp; fli; fli = fli->next)
2791 if (fli->f == f)
2792 break;
2793 if (! fli->started_p)
2795 fli->started_p = 1;
2797 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2798 put_mangled_filename (f, v->line.file);
2799 oprintf (f, "[] = {\n");
2802 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2803 v->name, v->name);
2806 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2807 "gt_ggc_deletable_rtab");
2809 for (v = variables; v; v = v->next)
2811 outf_p f = get_output_file_with_visibility (v->line.file);
2812 struct flist *fli;
2813 const char *if_marked = NULL;
2814 int length_p = 0;
2815 options_p o;
2817 for (o = v->opt; o; o = o->next)
2818 if (strcmp (o->name, "length") == 0)
2819 length_p = 1;
2820 else if (strcmp (o->name, "if_marked") == 0)
2821 if_marked = o->info;
2823 if (if_marked == NULL)
2824 continue;
2826 if (v->type->kind != TYPE_POINTER
2827 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2828 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2830 error_at_line (&v->line, "if_marked option used but not hash table");
2831 continue;
2834 for (fli = flp; fli; fli = fli->next)
2835 if (fli->f == f)
2836 break;
2837 if (! fli->started_p)
2839 fli->started_p = 1;
2841 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2842 put_mangled_filename (f, v->line.file);
2843 oprintf (f, "[] = {\n");
2846 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2847 v->name, length_p, &v->line, if_marked);
2850 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2851 "gt_ggc_cache_rtab");
2853 for (v = variables; v; v = v->next)
2855 outf_p f = get_output_file_with_visibility (v->line.file);
2856 struct flist *fli;
2857 int length_p = 0;
2858 int if_marked_p = 0;
2859 options_p o;
2861 for (o = v->opt; o; o = o->next)
2862 if (strcmp (o->name, "length") == 0)
2863 length_p = 1;
2864 else if (strcmp (o->name, "if_marked") == 0)
2865 if_marked_p = 1;
2867 if (! if_marked_p)
2868 continue;
2870 for (fli = flp; fli; fli = fli->next)
2871 if (fli->f == f)
2872 break;
2873 if (! fli->started_p)
2875 fli->started_p = 1;
2877 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2878 put_mangled_filename (f, v->line.file);
2879 oprintf (f, "[] = {\n");
2882 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2885 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2886 "gt_pch_cache_rtab");
2888 for (v = variables; v; v = v->next)
2890 outf_p f = get_output_file_with_visibility (v->line.file);
2891 struct flist *fli;
2892 int skip_p = 0;
2893 options_p o;
2895 for (o = v->opt; o; o = o->next)
2896 if (strcmp (o->name, "deletable") == 0
2897 || strcmp (o->name, "if_marked") == 0)
2898 skip_p = 1;
2900 if (skip_p)
2901 continue;
2903 if (! contains_scalar_p (v->type))
2904 continue;
2906 for (fli = flp; fli; fli = fli->next)
2907 if (fli->f == f)
2908 break;
2909 if (! fli->started_p)
2911 fli->started_p = 1;
2913 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2914 put_mangled_filename (f, v->line.file);
2915 oprintf (f, "[] = {\n");
2918 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2919 v->name, v->name);
2922 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2923 "gt_pch_scalar_rtab");
2927 extern int main (int argc, char **argv);
2929 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
2931 unsigned i;
2932 static struct fileloc pos = { __FILE__, __LINE__ };
2933 unsigned j;
2935 gen_rtx_next ();
2937 srcdir_len = strlen (srcdir);
2939 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
2940 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
2941 do_scalar_typedef ("uint8", &pos);
2942 do_scalar_typedef ("jword", &pos);
2943 do_scalar_typedef ("JCF_u2", &pos);
2944 #ifdef USE_MAPPED_LOCATION
2945 do_scalar_typedef ("location_t", &pos);
2946 do_scalar_typedef ("source_locus", &pos);
2947 #endif
2948 do_scalar_typedef ("void", &pos);
2950 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
2952 do_typedef ("HARD_REG_SET", create_array (
2953 create_scalar_type ("unsigned long", strlen ("unsigned long")),
2954 "2"), &pos);
2956 for (i = 0; i < NUM_GT_FILES; i++)
2958 int dupflag = 0;
2959 /* Omit if already seen. */
2960 for (j = 0; j < i; j++)
2962 if (!strcmp (all_files[i], all_files[j]))
2964 dupflag = 1;
2965 break;
2968 if (!dupflag)
2969 parse_file (all_files[i]);
2970 #ifndef USE_MAPPED_LOCATION
2971 /* temporary kludge - gengtype doesn't handle conditionals.
2972 Manually add source_locus *after* we've processed input.h. */
2973 if (i == 0)
2974 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
2975 #endif
2978 if (hit_error != 0)
2979 exit (1);
2981 set_gc_used (variables);
2983 open_base_files ();
2984 write_enum_defn (structures, param_structs);
2985 write_types (structures, param_structs, &ggc_wtd);
2986 write_types (structures, param_structs, &pch_wtd);
2987 write_local (structures, param_structs);
2988 write_roots (variables);
2989 write_rtx_next ();
2990 close_output_files ();
2992 return (hit_error != 0);