* gengtype.c (walk_type): Produce `not equal to' compares for loop
[official-gcc.git] / gcc / gengtype.c
blob37dbc5766679ad5f01764d3c6b2961d5a445d693
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 "errors.h"
29 /* Nonzero iff an error has occurred. */
30 static int hit_error = 0;
32 static void gen_rtx_next (void);
33 static void write_rtx_next (void);
34 static void open_base_files (void);
35 static void close_output_files (void);
37 /* Report an error at POS, printing MSG. */
39 void
40 error_at_line (struct fileloc *pos, const char *msg, ...)
42 va_list ap;
44 va_start (ap, msg);
46 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
47 vfprintf (stderr, msg, ap);
48 fputc ('\n', stderr);
49 hit_error = 1;
51 va_end (ap);
54 /* vasprintf, but produces fatal message on out-of-memory. */
55 int
56 xvasprintf (char **result, const char *format, va_list args)
58 int ret = vasprintf (result, format, args);
59 if (*result == NULL || ret < 0)
61 fputs ("gengtype: out of memory", stderr);
62 xexit (1);
64 return ret;
67 /* Wrapper for xvasprintf. */
68 char *
69 xasprintf (const char *format, ...)
71 char *result;
72 va_list ap;
74 va_start (ap, format);
75 xvasprintf (&result, format, ap);
76 va_end (ap);
77 return result;
80 /* The one and only TYPE_STRING. */
82 struct type string_type = {
83 TYPE_STRING, NULL, NULL, GC_USED, {0}
86 /* Lists of various things. */
88 static pair_p typedefs;
89 static type_p structures;
90 static type_p param_structs;
91 static pair_p variables;
93 static void do_scalar_typedef (const char *, struct fileloc *);
94 static type_p find_param_structure
95 (type_p t, type_p param[NUM_PARAM]);
96 static type_p adjust_field_tree_exp (type_p t, options_p opt);
97 static type_p adjust_field_rtx_def (type_p t, options_p opt);
99 /* Define S as a typedef to T at POS. */
101 void
102 do_typedef (const char *s, type_p t, struct fileloc *pos)
104 pair_p p;
106 for (p = typedefs; p != NULL; p = p->next)
107 if (strcmp (p->name, s) == 0)
109 if (p->type != t)
111 error_at_line (pos, "type `%s' previously defined", s);
112 error_at_line (&p->line, "previously defined here");
114 return;
117 p = XNEW (struct pair);
118 p->next = typedefs;
119 p->name = s;
120 p->type = t;
121 p->line = *pos;
122 typedefs = p;
125 /* Define S as a typename of a scalar. */
127 static void
128 do_scalar_typedef (const char *s, struct fileloc *pos)
130 do_typedef (s, create_scalar_type (s, strlen (s)), pos);
133 /* Return the type previously defined for S. Use POS to report errors. */
135 type_p
136 resolve_typedef (const char *s, struct fileloc *pos)
138 pair_p p;
139 for (p = typedefs; p != NULL; p = p->next)
140 if (strcmp (p->name, s) == 0)
141 return p->type;
142 error_at_line (pos, "unidentified type `%s'", s);
143 return create_scalar_type ("char", 4);
146 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
147 at POS with fields FIELDS and options O. */
149 void
150 new_structure (const char *name, int isunion, struct fileloc *pos,
151 pair_p fields, options_p o)
153 type_p si;
154 type_p s = NULL;
155 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
157 for (si = structures; si != NULL; si = si->next)
158 if (strcmp (name, si->u.s.tag) == 0
159 && UNION_P (si) == isunion)
161 type_p ls = NULL;
162 if (si->kind == TYPE_LANG_STRUCT)
164 ls = si;
166 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
167 if (si->u.s.bitmap == bitmap)
168 s = si;
170 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
172 ls = si;
173 si = XCNEW (struct type);
174 memcpy (si, ls, sizeof (struct type));
175 ls->kind = TYPE_LANG_STRUCT;
176 ls->u.s.lang_struct = si;
177 ls->u.s.fields = NULL;
178 si->next = NULL;
179 si->pointer_to = NULL;
180 si->u.s.lang_struct = ls;
182 else
183 s = si;
185 if (ls != NULL && s == NULL)
187 s = XCNEW (struct type);
188 s->next = ls->u.s.lang_struct;
189 ls->u.s.lang_struct = s;
190 s->u.s.lang_struct = ls;
192 break;
195 if (s == NULL)
197 s = XCNEW (struct type);
198 s->next = structures;
199 structures = s;
202 if (s->u.s.line.file != NULL
203 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
205 error_at_line (pos, "duplicate structure definition");
206 error_at_line (&s->u.s.line, "previous definition here");
209 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
210 s->u.s.tag = name;
211 s->u.s.line = *pos;
212 s->u.s.fields = fields;
213 s->u.s.opt = o;
214 s->u.s.bitmap = bitmap;
215 if (s->u.s.lang_struct)
216 s->u.s.lang_struct->u.s.bitmap |= bitmap;
219 /* Return the previously-defined structure with tag NAME (or a union
220 iff ISUNION is nonzero), or a new empty structure or union if none
221 was defined previously. */
223 type_p
224 find_structure (const char *name, int isunion)
226 type_p s;
228 for (s = structures; s != NULL; s = s->next)
229 if (strcmp (name, s->u.s.tag) == 0
230 && UNION_P (s) == isunion)
231 return s;
233 s = XCNEW (struct type);
234 s->next = structures;
235 structures = s;
236 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
237 s->u.s.tag = name;
238 structures = s;
239 return s;
242 /* Return the previously-defined parameterized structure for structure
243 T and parameters PARAM, or a new parameterized empty structure or
244 union if none was defined previously. */
246 static type_p
247 find_param_structure (type_p t, type_p param[NUM_PARAM])
249 type_p res;
251 for (res = param_structs; res; res = res->next)
252 if (res->u.param_struct.stru == t
253 && memcmp (res->u.param_struct.param, param,
254 sizeof (type_p) * NUM_PARAM) == 0)
255 break;
256 if (res == NULL)
258 res = XCNEW (struct type);
259 res->kind = TYPE_PARAM_STRUCT;
260 res->next = param_structs;
261 param_structs = res;
262 res->u.param_struct.stru = t;
263 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
265 return res;
268 /* Return a scalar type with name NAME. */
270 type_p
271 create_scalar_type (const char *name, size_t name_len)
273 type_p r = XCNEW (struct type);
274 r->kind = TYPE_SCALAR;
275 r->u.sc = (char *) xmemdup (name, name_len, name_len + 1);
276 return r;
279 /* Return a pointer to T. */
281 type_p
282 create_pointer (type_p t)
284 if (! t->pointer_to)
286 type_p r = XCNEW (struct type);
287 r->kind = TYPE_POINTER;
288 r->u.p = t;
289 t->pointer_to = r;
291 return t->pointer_to;
294 /* Return an array of length LEN. */
296 type_p
297 create_array (type_p t, const char *len)
299 type_p v;
301 v = XCNEW (struct type);
302 v->kind = TYPE_ARRAY;
303 v->u.a.p = t;
304 v->u.a.len = len;
305 return v;
308 /* Return an options structure with name NAME and info INFO. */
309 options_p
310 create_option (const char *name, void *info)
312 options_p o = XNEW (struct options);
313 o->name = name;
314 o->info = (const char*) info;
315 return o;
318 /* Add a variable named S of type T with options O defined at POS,
319 to `variables'. */
321 void
322 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
324 pair_p n;
325 n = XNEW (struct pair);
326 n->name = s;
327 n->type = t;
328 n->line = *pos;
329 n->opt = o;
330 n->next = variables;
331 variables = n;
334 /* We don't care how long a CONST_DOUBLE is. */
335 #define CONST_DOUBLE_FORMAT "ww"
336 /* We don't want to see codes that are only for generator files. */
337 #undef GENERATOR_FILE
339 enum rtx_code {
340 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
341 #include "rtl.def"
342 #undef DEF_RTL_EXPR
343 NUM_RTX_CODE
346 static const char * const rtx_name[NUM_RTX_CODE] = {
347 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
348 #include "rtl.def"
349 #undef DEF_RTL_EXPR
352 static const char * const rtx_format[NUM_RTX_CODE] = {
353 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
354 #include "rtl.def"
355 #undef DEF_RTL_EXPR
358 static int rtx_next_new[NUM_RTX_CODE];
360 /* We also need codes and names for insn notes (not register notes).
361 Note that we do *not* bias the note values here. */
362 enum insn_note {
363 #define DEF_INSN_NOTE(NAME) NAME,
364 #include "insn-notes.def"
365 #undef DEF_INSN_NOTE
367 NOTE_INSN_MAX
370 static const char *const note_insn_name[NOTE_INSN_MAX] = {
371 #define DEF_INSN_NOTE(NAME) #NAME,
372 #include "insn-notes.def"
373 #undef DEF_INSN_NOTE
376 #undef CONST_DOUBLE_FORMAT
377 #define GENERATOR_FILE
379 /* Generate the contents of the rtx_next array. This really doesn't belong
380 in gengtype at all, but it's needed for adjust_field_rtx_def. */
382 static void
383 gen_rtx_next (void)
385 int i;
386 for (i = 0; i < NUM_RTX_CODE; i++)
388 int k;
390 rtx_next_new[i] = -1;
391 if (strncmp (rtx_format[i], "iuu", 3) == 0)
392 rtx_next_new[i] = 2;
393 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
394 rtx_next_new[i] = 1;
395 else
396 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
397 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
398 rtx_next_new[i] = k;
402 /* Write out the contents of the rtx_next array. */
403 static void
404 write_rtx_next (void)
406 outf_p f = get_output_file_with_visibility (NULL);
407 int i;
409 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
410 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
411 for (i = 0; i < NUM_RTX_CODE; i++)
412 if (rtx_next_new[i] == -1)
413 oprintf (f, " 0,\n");
414 else
415 oprintf (f,
416 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
417 rtx_next_new[i]);
418 oprintf (f, "};\n");
421 /* Handle `special("rtx_def")'. This is a special case for field
422 `fld' of struct rtx_def, which is an array of unions whose values
423 are based in a complex way on the type of RTL. */
425 static type_p
426 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
428 pair_p flds = NULL;
429 options_p nodot;
430 int i;
431 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
432 type_p bitmap_tp, basic_block_tp, reg_attrs_tp;
434 if (t->kind != TYPE_UNION)
436 error_at_line (&lexer_line,
437 "special `rtx_def' must be applied to a union");
438 return &string_type;
441 nodot = XNEW (struct options);
442 nodot->next = NULL;
443 nodot->name = "dot";
444 nodot->info = "";
446 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
447 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
448 tree_tp = create_pointer (find_structure ("tree_node", 1));
449 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
450 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
451 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
452 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
453 scalar_tp = create_scalar_type ("rtunion scalar", 14);
456 pair_p note_flds = NULL;
457 int c;
459 for (c = 0; c <= NOTE_INSN_MAX; c++)
461 pair_p old_note_flds = note_flds;
463 note_flds = XNEW (struct pair);
464 note_flds->line.file = __FILE__;
465 note_flds->line.line = __LINE__;
466 note_flds->opt = XNEW (struct options);
467 note_flds->opt->next = nodot;
468 note_flds->opt->name = "tag";
469 note_flds->opt->info = note_insn_name[c];
470 note_flds->next = old_note_flds;
472 switch (c)
474 /* NOTE_INSN_MAX is used as the default field for line
475 number notes. */
476 case NOTE_INSN_MAX:
477 note_flds->opt->name = "default";
478 note_flds->name = "rt_str";
479 note_flds->type = &string_type;
480 break;
482 case NOTE_INSN_BLOCK_BEG:
483 case NOTE_INSN_BLOCK_END:
484 note_flds->name = "rt_tree";
485 note_flds->type = tree_tp;
486 break;
488 case NOTE_INSN_EXPECTED_VALUE:
489 case NOTE_INSN_VAR_LOCATION:
490 note_flds->name = "rt_rtx";
491 note_flds->type = rtx_tp;
492 break;
494 default:
495 note_flds->name = "rt_int";
496 note_flds->type = scalar_tp;
497 break;
500 new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL);
503 note_union_tp = find_structure ("rtx_def_note_subunion", 1);
505 for (i = 0; i < NUM_RTX_CODE; i++)
507 pair_p old_flds = flds;
508 pair_p subfields = NULL;
509 size_t aindex, nmindex;
510 const char *sname;
511 char *ftag;
513 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
515 pair_p old_subf = subfields;
516 type_p t;
517 const char *subname;
519 switch (rtx_format[i][aindex])
521 case '*':
522 case 'i':
523 case 'n':
524 case 'w':
525 t = scalar_tp;
526 subname = "rt_int";
527 break;
529 case '0':
530 if (i == MEM && aindex == 1)
531 t = mem_attrs_tp, subname = "rt_mem";
532 else if (i == JUMP_INSN && aindex == 9)
533 t = rtx_tp, subname = "rt_rtx";
534 else if (i == CODE_LABEL && aindex == 4)
535 t = scalar_tp, subname = "rt_int";
536 else if (i == CODE_LABEL && aindex == 5)
537 t = rtx_tp, subname = "rt_rtx";
538 else if (i == LABEL_REF
539 && (aindex == 1 || aindex == 2))
540 t = rtx_tp, subname = "rt_rtx";
541 else if (i == NOTE && aindex == 4)
542 t = note_union_tp, subname = "";
543 else if (i == NOTE && aindex >= 7)
544 t = scalar_tp, subname = "rt_int";
545 else if (i == ADDR_DIFF_VEC && aindex == 4)
546 t = scalar_tp, subname = "rt_int";
547 else if (i == VALUE && aindex == 0)
548 t = scalar_tp, subname = "rt_int";
549 else if (i == REG && aindex == 1)
550 t = scalar_tp, subname = "rt_int";
551 else if (i == REG && aindex == 2)
552 t = reg_attrs_tp, subname = "rt_reg";
553 else if (i == SCRATCH && aindex == 0)
554 t = scalar_tp, subname = "rt_int";
555 else if (i == SYMBOL_REF && aindex == 1)
556 t = scalar_tp, subname = "rt_int";
557 else if (i == SYMBOL_REF && aindex == 2)
558 t = tree_tp, subname = "rt_tree";
559 else if (i == BARRIER && aindex >= 3)
560 t = scalar_tp, subname = "rt_int";
561 else
563 error_at_line (&lexer_line,
564 "rtx type `%s' has `0' in position %lu, can't handle",
565 rtx_name[i], (unsigned long) aindex);
566 t = &string_type;
567 subname = "rt_int";
569 break;
571 case 's':
572 case 'S':
573 case 'T':
574 t = &string_type;
575 subname = "rt_str";
576 break;
578 case 'e':
579 case 'u':
580 t = rtx_tp;
581 subname = "rt_rtx";
582 break;
584 case 'E':
585 case 'V':
586 t = rtvec_tp;
587 subname = "rt_rtvec";
588 break;
590 case 't':
591 t = tree_tp;
592 subname = "rt_tree";
593 break;
595 case 'b':
596 t = bitmap_tp;
597 subname = "rt_bit";
598 break;
600 case 'B':
601 t = basic_block_tp;
602 subname = "rt_bb";
603 break;
605 default:
606 error_at_line (&lexer_line,
607 "rtx type `%s' has `%c' in position %lu, can't handle",
608 rtx_name[i], rtx_format[i][aindex],
609 (unsigned long)aindex);
610 t = &string_type;
611 subname = "rt_int";
612 break;
615 subfields = XNEW (struct pair);
616 subfields->next = old_subf;
617 subfields->type = t;
618 subfields->name = xasprintf (".fld[%lu].%s", (unsigned long)aindex,
619 subname);
620 subfields->line.file = __FILE__;
621 subfields->line.line = __LINE__;
622 if (t == note_union_tp)
624 subfields->opt = XNEW (struct options);
625 subfields->opt->next = nodot;
626 subfields->opt->name = "desc";
627 subfields->opt->info = "NOTE_LINE_NUMBER (&%0)";
629 else if (t == basic_block_tp)
631 /* We don't presently GC basic block structures... */
632 subfields->opt = XNEW (struct options);
633 subfields->opt->next = nodot;
634 subfields->opt->name = "skip";
635 subfields->opt->info = NULL;
637 else
638 subfields->opt = nodot;
641 flds = XNEW (struct pair);
642 flds->next = old_flds;
643 flds->name = "";
644 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
645 new_structure (sname, 0, &lexer_line, subfields, NULL);
646 flds->type = find_structure (sname, 0);
647 flds->line.file = __FILE__;
648 flds->line.line = __LINE__;
649 flds->opt = XNEW (struct options);
650 flds->opt->next = nodot;
651 flds->opt->name = "tag";
652 ftag = xstrdup (rtx_name[i]);
653 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
654 ftag[nmindex] = TOUPPER (ftag[nmindex]);
655 flds->opt->info = ftag;
658 new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
659 return find_structure ("rtx_def_subunion", 1);
662 /* Handle `special("tree_exp")'. This is a special case for
663 field `operands' of struct tree_exp, which although it claims to contain
664 pointers to trees, actually sometimes contains pointers to RTL too.
665 Passed T, the old type of the field, and OPT its options. Returns
666 a new type for the field. */
668 static type_p
669 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
671 pair_p flds;
672 options_p nodot;
674 if (t->kind != TYPE_ARRAY)
676 error_at_line (&lexer_line,
677 "special `tree_exp' must be applied to an array");
678 return &string_type;
681 nodot = XNEW (struct options);
682 nodot->next = NULL;
683 nodot->name = "dot";
684 nodot->info = "";
686 flds = XNEW (struct pair);
687 flds->next = NULL;
688 flds->name = "";
689 flds->type = t;
690 flds->line.file = __FILE__;
691 flds->line.line = __LINE__;
692 flds->opt = XNEW (struct options);
693 flds->opt->next = nodot;
694 flds->opt->name = "length";
695 flds->opt->info = "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
697 options_p oldopt = flds->opt;
698 flds->opt = XNEW (struct options);
699 flds->opt->next = oldopt;
700 flds->opt->name = "default";
701 flds->opt->info = "";
704 new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
705 return find_structure ("tree_exp_subunion", 1);
708 /* Perform any special processing on a type T, about to become the type
709 of a field. Return the appropriate type for the field.
710 At present:
711 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
712 - Similarly for arrays of pointer-to-char;
713 - Converts structures for which a parameter is provided to
714 TYPE_PARAM_STRUCT;
715 - Handles "special" options.
718 type_p
719 adjust_field_type (type_p t, options_p opt)
721 int length_p = 0;
722 const int pointer_p = t->kind == TYPE_POINTER;
723 type_p params[NUM_PARAM];
724 int params_p = 0;
725 int i;
727 for (i = 0; i < NUM_PARAM; i++)
728 params[i] = NULL;
730 for (; opt; opt = opt->next)
731 if (strcmp (opt->name, "length") == 0)
732 length_p = 1;
733 else if (strcmp (opt->name, "param_is") == 0
734 || (strncmp (opt->name, "param", 5) == 0
735 && ISDIGIT (opt->name[5])
736 && strcmp (opt->name + 6, "_is") == 0))
738 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
740 if (! UNION_OR_STRUCT_P (t)
741 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
743 error_at_line (&lexer_line,
744 "option `%s' may only be applied to structures or structure pointers",
745 opt->name);
746 return t;
749 params_p = 1;
750 if (params[num] != NULL)
751 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
752 if (! ISDIGIT (opt->name[5]))
753 params[num] = create_pointer ((type_p) opt->info);
754 else
755 params[num] = (type_p) opt->info;
757 else if (strcmp (opt->name, "special") == 0)
759 const char *special_name = opt->info;
760 if (strcmp (special_name, "tree_exp") == 0)
761 t = adjust_field_tree_exp (t, opt);
762 else if (strcmp (special_name, "rtx_def") == 0)
763 t = adjust_field_rtx_def (t, opt);
764 else
765 error_at_line (&lexer_line, "unknown special `%s'", special_name);
768 if (params_p)
770 type_p realt;
772 if (pointer_p)
773 t = t->u.p;
774 realt = find_param_structure (t, params);
775 t = pointer_p ? create_pointer (realt) : realt;
778 if (! length_p
779 && pointer_p
780 && t->u.p->kind == TYPE_SCALAR
781 && (strcmp (t->u.p->u.sc, "char") == 0
782 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
783 return &string_type;
784 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
785 && t->u.a.p->u.p->kind == TYPE_SCALAR
786 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
787 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
788 return create_array (&string_type, t->u.a.len);
790 return t;
793 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
794 and information about the correspondence between token types and fields
795 in TYPEINFO. POS is used for error messages. */
797 void
798 note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
799 struct fileloc *pos)
801 pair_p p;
802 pair_p *p_p;
804 for (p = typeinfo; p; p = p->next)
806 pair_p m;
808 if (p->name == NULL)
809 continue;
811 if (p->type == (type_p) 1)
813 pair_p pp;
814 int ok = 0;
816 for (pp = typeinfo; pp; pp = pp->next)
817 if (pp->type != (type_p) 1
818 && strcmp (pp->opt->info, p->opt->info) == 0)
820 ok = 1;
821 break;
823 if (! ok)
824 continue;
827 for (m = fields; m; m = m->next)
828 if (strcmp (m->name, p->name) == 0)
829 p->type = m->type;
830 if (p->type == NULL)
832 error_at_line (&p->line,
833 "couldn't match fieldname `%s'", p->name);
834 p->name = NULL;
838 p_p = &typeinfo;
839 while (*p_p)
841 pair_p p = *p_p;
843 if (p->name == NULL
844 || p->type == (type_p) 1)
845 *p_p = p->next;
846 else
847 p_p = &p->next;
850 new_structure ("yy_union", 1, pos, typeinfo, o);
851 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
854 static void process_gc_options (options_p, enum gc_used_enum,
855 int *, int *, int *, type_p *);
856 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
857 static void set_gc_used (pair_p);
859 /* Handle OPT for set_gc_used_type. */
861 static void
862 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
863 int *pass_param, int *length, type_p *nested_ptr)
865 options_p o;
866 for (o = opt; o; o = o->next)
867 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
868 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
869 else if (strcmp (o->name, "maybe_undef") == 0)
870 *maybe_undef = 1;
871 else if (strcmp (o->name, "use_params") == 0)
872 *pass_param = 1;
873 else if (strcmp (o->name, "length") == 0)
874 *length = 1;
875 else if (strcmp (o->name, "nested_ptr") == 0)
876 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
879 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
881 static void
882 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
884 if (t->gc_used >= level)
885 return;
887 t->gc_used = level;
889 switch (t->kind)
891 case TYPE_STRUCT:
892 case TYPE_UNION:
894 pair_p f;
895 int dummy;
896 type_p dummy2;
898 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy,
899 &dummy2);
901 for (f = t->u.s.fields; f; f = f->next)
903 int maybe_undef = 0;
904 int pass_param = 0;
905 int length = 0;
906 type_p nested_ptr = NULL;
907 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
908 &length, &nested_ptr);
910 if (nested_ptr && f->type->kind == TYPE_POINTER)
911 set_gc_used_type (nested_ptr, GC_POINTED_TO,
912 pass_param ? param : NULL);
913 else if (length && f->type->kind == TYPE_POINTER)
914 set_gc_used_type (f->type->u.p, GC_USED, NULL);
915 else if (maybe_undef && f->type->kind == TYPE_POINTER)
916 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
917 else if (pass_param && f->type->kind == TYPE_POINTER && param)
918 set_gc_used_type (find_param_structure (f->type->u.p, param),
919 GC_POINTED_TO, NULL);
920 else
921 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
923 break;
926 case TYPE_POINTER:
927 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
928 break;
930 case TYPE_ARRAY:
931 set_gc_used_type (t->u.a.p, GC_USED, param);
932 break;
934 case TYPE_LANG_STRUCT:
935 for (t = t->u.s.lang_struct; t; t = t->next)
936 set_gc_used_type (t, level, param);
937 break;
939 case TYPE_PARAM_STRUCT:
941 int i;
942 for (i = 0; i < NUM_PARAM; i++)
943 if (t->u.param_struct.param[i] != 0)
944 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
946 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
947 level = GC_POINTED_TO;
948 else
949 level = GC_USED;
950 t->u.param_struct.stru->gc_used = GC_UNUSED;
951 set_gc_used_type (t->u.param_struct.stru, level,
952 t->u.param_struct.param);
953 break;
955 default:
956 break;
960 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
962 static void
963 set_gc_used (pair_p variables)
965 pair_p p;
966 for (p = variables; p; p = p->next)
967 set_gc_used_type (p->type, GC_USED, NULL);
970 /* File mapping routines. For each input file, there is one output .c file
971 (but some output files have many input files), and there is one .h file
972 for the whole build. */
974 /* The list of output files. */
975 static outf_p output_files;
977 /* The output header file that is included into pretty much every
978 source file. */
979 static outf_p header_file;
981 /* Number of files specified in gtfiles. */
982 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
984 /* Number of files in the language files array. */
985 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
987 /* Length of srcdir name. */
988 static int srcdir_len = 0;
990 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
991 outf_p base_files[NUM_BASE_FILES];
993 static outf_p create_file (const char *, const char *);
994 static const char * get_file_basename (const char *);
996 /* Create and return an outf_p for a new file for NAME, to be called
997 ONAME. */
999 static outf_p
1000 create_file (const char *name, const char *oname)
1002 static const char *const hdr[] = {
1003 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
1004 "\n",
1005 "This file is part of GCC.\n",
1006 "\n",
1007 "GCC is free software; you can redistribute it and/or modify it under\n",
1008 "the terms of the GNU General Public License as published by the Free\n",
1009 "Software Foundation; either version 2, or (at your option) any later\n",
1010 "version.\n",
1011 "\n",
1012 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1013 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1014 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1015 "for more details.\n",
1016 "\n",
1017 "You should have received a copy of the GNU General Public License\n",
1018 "along with GCC; see the file COPYING. If not, write to the Free\n",
1019 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
1020 "02111-1307, USA. */\n",
1021 "\n",
1022 "/* This file is machine generated. Do not edit. */\n"
1024 outf_p f;
1025 size_t i;
1027 f = XCNEW (struct outf);
1028 f->next = output_files;
1029 f->name = oname;
1030 output_files = f;
1032 oprintf (f, "/* Type information for %s.\n", name);
1033 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1034 oprintf (f, "%s", hdr[i]);
1035 return f;
1038 /* Print, like fprintf, to O. */
1039 void
1040 oprintf (outf_p o, const char *format, ...)
1042 char *s;
1043 size_t slength;
1044 va_list ap;
1046 va_start (ap, format);
1047 slength = xvasprintf (&s, format, ap);
1049 if (o->bufused + slength > o->buflength)
1051 size_t new_len = o->buflength;
1052 if (new_len == 0)
1053 new_len = 1024;
1054 do {
1055 new_len *= 2;
1056 } while (o->bufused + slength >= new_len);
1057 o->buf = XRESIZEVEC (char, o->buf, new_len);
1058 o->buflength = new_len;
1060 memcpy (o->buf + o->bufused, s, slength);
1061 o->bufused += slength;
1062 free (s);
1063 va_end (ap);
1066 /* Open the global header file and the language-specific header files. */
1068 static void
1069 open_base_files (void)
1071 size_t i;
1073 header_file = create_file ("GCC", "gtype-desc.h");
1075 for (i = 0; i < NUM_BASE_FILES; i++)
1076 base_files[i] = create_file (lang_dir_names[i],
1077 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1079 /* gtype-desc.c is a little special, so we create it here. */
1081 /* The order of files here matters very much. */
1082 static const char *const ifiles [] = {
1083 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1084 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1085 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1086 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1087 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1088 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1089 NULL
1091 const char *const *ifp;
1092 outf_p gtype_desc_c;
1094 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1095 for (ifp = ifiles; *ifp; ifp++)
1096 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1100 /* Determine the pathname to F relative to $(srcdir). */
1102 static const char *
1103 get_file_basename (const char *f)
1105 const char *basename;
1106 unsigned i;
1108 basename = strrchr (f, '/');
1110 if (!basename)
1111 return f;
1113 basename++;
1115 for (i = 1; i < NUM_BASE_FILES; i++)
1117 const char * s1;
1118 const char * s2;
1119 int l1;
1120 int l2;
1121 s1 = basename - strlen (lang_dir_names [i]) - 1;
1122 s2 = lang_dir_names [i];
1123 l1 = strlen (s1);
1124 l2 = strlen (s2);
1125 if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1127 basename -= l2 + 1;
1128 if ((basename - f - 1) != srcdir_len)
1129 fatal ("filename `%s' should be preceded by $srcdir", f);
1130 break;
1134 return basename;
1137 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1138 INPUT_FILE is used by <lang>.
1140 This function should be written to assume that a file _is_ used
1141 if the situation is unclear. If it wrongly assumes a file _is_ used,
1142 a linker error will result. If it wrongly assumes a file _is not_ used,
1143 some GC roots may be missed, which is a much harder-to-debug problem. */
1145 unsigned
1146 get_base_file_bitmap (const char *input_file)
1148 const char *basename = get_file_basename (input_file);
1149 const char *slashpos = strchr (basename, '/');
1150 unsigned j;
1151 unsigned k;
1152 unsigned bitmap;
1154 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1155 it belongs to the corresponding language. The file may belong to other
1156 languages as well (which is checked for below). */
1158 if (slashpos)
1160 size_t i;
1161 for (i = 1; i < NUM_BASE_FILES; i++)
1162 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1163 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1165 /* It's in a language directory, set that language. */
1166 bitmap = 1 << i;
1170 /* If it's in any config-lang.in, then set for the languages
1171 specified. */
1173 bitmap = 0;
1175 for (j = 0; j < NUM_LANG_FILES; j++)
1177 if (!strcmp(input_file, lang_files[j]))
1179 for (k = 0; k < NUM_BASE_FILES; k++)
1181 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1182 bitmap |= (1 << k);
1187 /* Otherwise, set all languages. */
1188 if (!bitmap)
1189 bitmap = (1 << NUM_BASE_FILES) - 1;
1191 return bitmap;
1194 /* An output file, suitable for definitions, that can see declarations
1195 made in INPUT_FILE and is linked into every language that uses
1196 INPUT_FILE. */
1198 outf_p
1199 get_output_file_with_visibility (const char *input_file)
1201 outf_p r;
1202 size_t len;
1203 const char *basename;
1204 const char *for_name;
1205 const char *output_name;
1207 /* This can happen when we need a file with visibility on a
1208 structure that we've never seen. We have to just hope that it's
1209 globally visible. */
1210 if (input_file == NULL)
1211 input_file = "system.h";
1213 /* Determine the output file name. */
1214 basename = get_file_basename (input_file);
1216 len = strlen (basename);
1217 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1218 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1219 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1221 char *s;
1223 output_name = s = xasprintf ("gt-%s", basename);
1224 for (; *s != '.'; s++)
1225 if (! ISALNUM (*s) && *s != '-')
1226 *s = '-';
1227 memcpy (s, ".h", sizeof (".h"));
1228 for_name = basename;
1230 /* Some headers get used by more than one front-end; hence, it
1231 would be inappropriate to spew them out to a single gtype-<lang>.h
1232 (and gengtype doesn't know how to direct spewage into multiple
1233 gtype-<lang>.h headers at this time). Instead, we pair up these
1234 headers with source files (and their special purpose gt-*.h headers). */
1235 else if (strcmp (basename, "c-common.h") == 0)
1236 output_name = "gt-c-common.h", for_name = "c-common.c";
1237 else if (strcmp (basename, "c-tree.h") == 0)
1238 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1239 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1240 && strcmp (basename + 5, "objc-act.h") == 0)
1241 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1242 else
1244 size_t i;
1246 for (i = 0; i < NUM_BASE_FILES; i++)
1247 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1248 && basename[strlen(lang_dir_names[i])] == '/')
1249 return base_files[i];
1251 output_name = "gtype-desc.c";
1252 for_name = NULL;
1255 /* Look through to see if we've ever seen this output filename before. */
1256 for (r = output_files; r; r = r->next)
1257 if (strcmp (r->name, output_name) == 0)
1258 return r;
1260 /* If not, create it. */
1261 r = create_file (for_name, output_name);
1263 return r;
1266 /* The name of an output file, suitable for definitions, that can see
1267 declarations made in INPUT_FILE and is linked into every language
1268 that uses INPUT_FILE. */
1270 const char *
1271 get_output_file_name (const char *input_file)
1273 return get_output_file_with_visibility (input_file)->name;
1276 /* Copy the output to its final destination,
1277 but don't unnecessarily change modification times. */
1279 static void
1280 close_output_files (void)
1282 outf_p of;
1284 for (of = output_files; of; of = of->next)
1286 FILE * newfile;
1288 newfile = fopen (of->name, "r");
1289 if (newfile != NULL )
1291 int no_write_p;
1292 size_t i;
1294 for (i = 0; i < of->bufused; i++)
1296 int ch;
1297 ch = fgetc (newfile);
1298 if (ch == EOF || ch != (unsigned char) of->buf[i])
1299 break;
1301 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1302 fclose (newfile);
1304 if (no_write_p)
1305 continue;
1308 newfile = fopen (of->name, "w");
1309 if (newfile == NULL)
1311 perror ("opening output file");
1312 exit (1);
1314 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1316 perror ("writing output file");
1317 exit (1);
1319 if (fclose (newfile) != 0)
1321 perror ("closing output file");
1322 exit (1);
1327 struct flist {
1328 struct flist *next;
1329 int started_p;
1330 const char *name;
1331 outf_p f;
1334 struct walk_type_data;
1336 /* For scalars and strings, given the item in 'val'.
1337 For structures, given a pointer to the item in 'val'.
1338 For misc. pointers, given the item in 'val'.
1340 typedef void (*process_field_fn)
1341 (type_p f, const struct walk_type_data *p);
1342 typedef void (*func_name_fn)
1343 (type_p s, const struct walk_type_data *p);
1345 /* Parameters for write_types. */
1347 struct write_types_data
1349 const char *prefix;
1350 const char *param_prefix;
1351 const char *subfield_marker_routine;
1352 const char *marker_routine;
1353 const char *reorder_note_routine;
1354 const char *comment;
1357 static void output_escaped_param (struct walk_type_data *d,
1358 const char *, const char *);
1359 static void output_mangled_typename (outf_p, type_p);
1360 static void walk_type (type_p t, struct walk_type_data *d);
1361 static void write_func_for_structure
1362 (type_p orig_s, type_p s, type_p * param,
1363 const struct write_types_data *wtd);
1364 static void write_types_process_field
1365 (type_p f, const struct walk_type_data *d);
1366 static void write_types (type_p structures,
1367 type_p param_structs,
1368 const struct write_types_data *wtd);
1369 static void write_types_local_process_field
1370 (type_p f, const struct walk_type_data *d);
1371 static void write_local_func_for_structure
1372 (type_p orig_s, type_p s, type_p * param);
1373 static void write_local (type_p structures,
1374 type_p param_structs);
1375 static void write_enum_defn (type_p structures, type_p param_structs);
1376 static int contains_scalar_p (type_p t);
1377 static void put_mangled_filename (outf_p , const char *);
1378 static void finish_root_table (struct flist *flp, const char *pfx,
1379 const char *tname, const char *lastname,
1380 const char *name);
1381 static void write_root (outf_p , pair_p, type_p, const char *, int,
1382 struct fileloc *, const char *);
1383 static void write_array (outf_p f, pair_p v,
1384 const struct write_types_data *wtd);
1385 static void write_roots (pair_p);
1387 /* Parameters for walk_type. */
1389 struct walk_type_data
1391 process_field_fn process_field;
1392 const void *cookie;
1393 outf_p of;
1394 options_p opt;
1395 const char *val;
1396 const char *prev_val[4];
1397 int indent;
1398 int counter;
1399 struct fileloc *line;
1400 lang_bitmap bitmap;
1401 type_p *param;
1402 int used_length;
1403 type_p orig_s;
1404 const char *reorder_fn;
1405 bool needs_cast_p;
1406 bool fn_wants_lvalue;
1409 /* Print a mangled name representing T to OF. */
1411 static void
1412 output_mangled_typename (outf_p of, type_p t)
1414 if (t == NULL)
1415 oprintf (of, "Z");
1416 else switch (t->kind)
1418 case TYPE_POINTER:
1419 oprintf (of, "P");
1420 output_mangled_typename (of, t->u.p);
1421 break;
1422 case TYPE_SCALAR:
1423 oprintf (of, "I");
1424 break;
1425 case TYPE_STRING:
1426 oprintf (of, "S");
1427 break;
1428 case TYPE_STRUCT:
1429 case TYPE_UNION:
1430 case TYPE_LANG_STRUCT:
1431 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1432 break;
1433 case TYPE_PARAM_STRUCT:
1435 int i;
1436 for (i = 0; i < NUM_PARAM; i++)
1437 if (t->u.param_struct.param[i] != NULL)
1438 output_mangled_typename (of, t->u.param_struct.param[i]);
1439 output_mangled_typename (of, t->u.param_struct.stru);
1441 break;
1442 case TYPE_ARRAY:
1443 gcc_unreachable ();
1447 /* Print PARAM to D->OF processing escapes. D->VAL references the
1448 current object, D->PREV_VAL the object containing the current
1449 object, ONAME is the name of the option and D->LINE is used to
1450 print error messages. */
1452 static void
1453 output_escaped_param (struct walk_type_data *d, const char *param,
1454 const char *oname)
1456 const char *p;
1458 for (p = param; *p; p++)
1459 if (*p != '%')
1460 oprintf (d->of, "%c", *p);
1461 else switch (*++p)
1463 case 'h':
1464 oprintf (d->of, "(%s)", d->prev_val[2]);
1465 break;
1466 case '0':
1467 oprintf (d->of, "(%s)", d->prev_val[0]);
1468 break;
1469 case '1':
1470 oprintf (d->of, "(%s)", d->prev_val[1]);
1471 break;
1472 case 'a':
1474 const char *pp = d->val + strlen (d->val);
1475 while (pp[-1] == ']')
1476 while (*pp != '[')
1477 pp--;
1478 oprintf (d->of, "%s", pp);
1480 break;
1481 default:
1482 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1483 oname, '%', *p);
1487 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1488 which is of type T. Write code to D->OF to constrain execution (at
1489 the point that D->PROCESS_FIELD is called) to the appropriate
1490 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1491 pointers to those objects. D->PREV_VAL lists the objects
1492 containing the current object, D->OPT is a list of options to
1493 apply, D->INDENT is the current indentation level, D->LINE is used
1494 to print error messages, D->BITMAP indicates which languages to
1495 print the structure for, and D->PARAM is the current parameter
1496 (from an enclosing param_is option). */
1498 static void
1499 walk_type (type_p t, struct walk_type_data *d)
1501 const char *length = NULL;
1502 const char *desc = NULL;
1503 int maybe_undef_p = 0;
1504 int use_param_num = -1;
1505 int use_params_p = 0;
1506 options_p oo;
1507 const struct nested_ptr_data *nested_ptr_d = NULL;
1509 d->needs_cast_p = false;
1510 for (oo = d->opt; oo; oo = oo->next)
1511 if (strcmp (oo->name, "length") == 0)
1512 length = oo->info;
1513 else if (strcmp (oo->name, "maybe_undef") == 0)
1514 maybe_undef_p = 1;
1515 else if (strncmp (oo->name, "use_param", 9) == 0
1516 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1517 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1518 else if (strcmp (oo->name, "use_params") == 0)
1519 use_params_p = 1;
1520 else if (strcmp (oo->name, "desc") == 0)
1521 desc = oo->info;
1522 else if (strcmp (oo->name, "nested_ptr") == 0)
1523 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1524 else if (strcmp (oo->name, "dot") == 0)
1526 else if (strcmp (oo->name, "tag") == 0)
1528 else if (strcmp (oo->name, "special") == 0)
1530 else if (strcmp (oo->name, "skip") == 0)
1532 else if (strcmp (oo->name, "default") == 0)
1534 else if (strcmp (oo->name, "descbits") == 0)
1536 else if (strcmp (oo->name, "param_is") == 0)
1538 else if (strncmp (oo->name, "param", 5) == 0
1539 && ISDIGIT (oo->name[5])
1540 && strcmp (oo->name + 6, "_is") == 0)
1542 else if (strcmp (oo->name, "chain_next") == 0)
1544 else if (strcmp (oo->name, "chain_prev") == 0)
1546 else if (strcmp (oo->name, "reorder") == 0)
1548 else
1549 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1551 if (d->used_length)
1552 length = NULL;
1554 if (use_params_p)
1556 int pointer_p = t->kind == TYPE_POINTER;
1558 if (pointer_p)
1559 t = t->u.p;
1560 if (! UNION_OR_STRUCT_P (t))
1561 error_at_line (d->line, "`use_params' option on unimplemented type");
1562 else
1563 t = find_param_structure (t, d->param);
1564 if (pointer_p)
1565 t = create_pointer (t);
1568 if (use_param_num != -1)
1570 if (d->param != NULL && d->param[use_param_num] != NULL)
1572 type_p nt = d->param[use_param_num];
1574 if (t->kind == TYPE_ARRAY)
1575 nt = create_array (nt, t->u.a.len);
1576 else if (length != NULL && t->kind == TYPE_POINTER)
1577 nt = create_pointer (nt);
1578 d->needs_cast_p = (t->kind != TYPE_POINTER
1579 && (nt->kind == TYPE_POINTER
1580 || nt->kind == TYPE_STRING));
1581 t = nt;
1583 else
1584 error_at_line (d->line, "no parameter defined for `%s'",
1585 d->val);
1588 if (maybe_undef_p
1589 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1591 error_at_line (d->line,
1592 "field `%s' has invalid option `maybe_undef_p'\n",
1593 d->val);
1594 return;
1597 switch (t->kind)
1599 case TYPE_SCALAR:
1600 case TYPE_STRING:
1601 d->process_field (t, d);
1602 break;
1604 case TYPE_POINTER:
1606 if (maybe_undef_p
1607 && t->u.p->u.s.line.file == NULL)
1609 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1610 break;
1613 if (! length)
1615 if (! UNION_OR_STRUCT_P (t->u.p)
1616 && t->u.p->kind != TYPE_PARAM_STRUCT)
1618 error_at_line (d->line,
1619 "field `%s' is pointer to unimplemented type",
1620 d->val);
1621 break;
1624 if (nested_ptr_d)
1626 const char *oldprevval2 = d->prev_val[2];
1628 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1630 error_at_line (d->line,
1631 "field `%s' has invalid "
1632 "option `nested_ptr'\n",
1633 d->val);
1634 return;
1637 d->prev_val[2] = d->val;
1638 oprintf (d->of, "%*s{\n", d->indent, "");
1639 d->indent += 2;
1640 d->val = xasprintf ("x%d", d->counter++);
1641 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1642 (nested_ptr_d->type->kind == TYPE_UNION
1643 ? "union" : "struct"),
1644 nested_ptr_d->type->u.s.tag,
1645 d->fn_wants_lvalue ? "" : "const ",
1646 d->val);
1647 oprintf (d->of, "%*s", d->indent + 2, "");
1648 output_escaped_param (d, nested_ptr_d->convert_from,
1649 "nested_ptr");
1650 oprintf (d->of, ";\n");
1652 d->process_field (nested_ptr_d->type, d);
1654 if (d->fn_wants_lvalue)
1656 oprintf (d->of, "%*s%s = ", d->indent, "",
1657 d->prev_val[2]);
1658 d->prev_val[2] = d->val;
1659 output_escaped_param (d, nested_ptr_d->convert_to,
1660 "nested_ptr");
1661 oprintf (d->of, ";\n");
1664 d->indent -= 2;
1665 oprintf (d->of, "%*s}\n", d->indent, "");
1666 d->val = d->prev_val[2];
1667 d->prev_val[2] = oldprevval2;
1669 else
1670 d->process_field (t->u.p, d);
1672 else
1674 int loopcounter = d->counter++;
1675 const char *oldval = d->val;
1676 const char *oldprevval3 = d->prev_val[3];
1677 char *newval;
1679 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1680 d->indent += 2;
1681 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1682 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1683 loopcounter, loopcounter);
1684 output_escaped_param (d, length, "length");
1685 oprintf (d->of, "); i%d++) {\n", loopcounter);
1686 d->indent += 2;
1687 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1688 d->used_length = 1;
1689 d->prev_val[3] = oldval;
1690 walk_type (t->u.p, d);
1691 free (newval);
1692 d->val = oldval;
1693 d->prev_val[3] = oldprevval3;
1694 d->used_length = 0;
1695 d->indent -= 2;
1696 oprintf (d->of, "%*s}\n", d->indent, "");
1697 d->process_field(t, d);
1698 d->indent -= 2;
1699 oprintf (d->of, "%*s}\n", d->indent, "");
1702 break;
1704 case TYPE_ARRAY:
1706 int loopcounter = d->counter++;
1707 const char *oldval = d->val;
1708 char *newval;
1710 /* If it's an array of scalars, we optimize by not generating
1711 any code. */
1712 if (t->u.a.p->kind == TYPE_SCALAR)
1713 break;
1715 oprintf (d->of, "%*s{\n", d->indent, "");
1716 d->indent += 2;
1717 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1718 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1719 loopcounter, loopcounter);
1720 if (length)
1721 output_escaped_param (d, length, "length");
1722 else
1723 oprintf (d->of, "%s", t->u.a.len);
1724 oprintf (d->of, "); i%d++) {\n", loopcounter);
1725 d->indent += 2;
1726 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1727 d->used_length = 1;
1728 walk_type (t->u.a.p, d);
1729 free (newval);
1730 d->used_length = 0;
1731 d->val = oldval;
1732 d->indent -= 2;
1733 oprintf (d->of, "%*s}\n", d->indent, "");
1734 d->indent -= 2;
1735 oprintf (d->of, "%*s}\n", d->indent, "");
1737 break;
1739 case TYPE_STRUCT:
1740 case TYPE_UNION:
1742 pair_p f;
1743 const char *oldval = d->val;
1744 const char *oldprevval1 = d->prev_val[1];
1745 const char *oldprevval2 = d->prev_val[2];
1746 const int union_p = t->kind == TYPE_UNION;
1747 int seen_default_p = 0;
1748 options_p o;
1750 if (! t->u.s.line.file)
1751 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1753 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1755 error_at_line (d->line,
1756 "structure `%s' defined for mismatching languages",
1757 t->u.s.tag);
1758 error_at_line (&t->u.s.line, "one structure defined here");
1761 /* Some things may also be defined in the structure's options. */
1762 for (o = t->u.s.opt; o; o = o->next)
1763 if (! desc && strcmp (o->name, "desc") == 0)
1764 desc = o->info;
1766 d->prev_val[2] = oldval;
1767 d->prev_val[1] = oldprevval2;
1768 if (union_p)
1770 if (desc == NULL)
1772 error_at_line (d->line, "missing `desc' option for union `%s'",
1773 t->u.s.tag);
1774 desc = "1";
1776 oprintf (d->of, "%*sswitch (", d->indent, "");
1777 output_escaped_param (d, desc, "desc");
1778 oprintf (d->of, ")\n");
1779 d->indent += 2;
1780 oprintf (d->of, "%*s{\n", d->indent, "");
1782 for (f = t->u.s.fields; f; f = f->next)
1784 options_p oo;
1785 const char *dot = ".";
1786 const char *tagid = NULL;
1787 int skip_p = 0;
1788 int default_p = 0;
1789 int use_param_p = 0;
1790 char *newval;
1792 d->reorder_fn = NULL;
1793 for (oo = f->opt; oo; oo = oo->next)
1794 if (strcmp (oo->name, "dot") == 0)
1795 dot = oo->info;
1796 else if (strcmp (oo->name, "tag") == 0)
1797 tagid = oo->info;
1798 else if (strcmp (oo->name, "skip") == 0)
1799 skip_p = 1;
1800 else if (strcmp (oo->name, "default") == 0)
1801 default_p = 1;
1802 else if (strcmp (oo->name, "reorder") == 0)
1803 d->reorder_fn = oo->info;
1804 else if (strncmp (oo->name, "use_param", 9) == 0
1805 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1806 use_param_p = 1;
1808 if (skip_p)
1809 continue;
1811 if (union_p && tagid)
1813 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1814 d->indent += 2;
1816 else if (union_p && default_p)
1818 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1819 d->indent += 2;
1820 seen_default_p = 1;
1822 else if (! union_p && (default_p || tagid))
1823 error_at_line (d->line,
1824 "can't use `%s' outside a union on field `%s'",
1825 default_p ? "default" : "tag", f->name);
1826 else if (union_p && ! (default_p || tagid)
1827 && f->type->kind == TYPE_SCALAR)
1829 fprintf (stderr,
1830 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1831 d->line->file, d->line->line, f->name);
1832 continue;
1834 else if (union_p && ! (default_p || tagid))
1835 error_at_line (d->line,
1836 "field `%s' is missing `tag' or `default' option",
1837 f->name);
1839 d->line = &f->line;
1840 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1841 d->opt = f->opt;
1842 d->used_length = false;
1844 if (union_p && use_param_p && d->param == NULL)
1845 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1846 else
1847 walk_type (f->type, d);
1849 free (newval);
1851 if (union_p)
1853 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1854 d->indent -= 2;
1857 d->reorder_fn = NULL;
1859 d->val = oldval;
1860 d->prev_val[1] = oldprevval1;
1861 d->prev_val[2] = oldprevval2;
1863 if (union_p && ! seen_default_p)
1865 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1866 oprintf (d->of, "%*s break;\n", d->indent, "");
1868 if (union_p)
1870 oprintf (d->of, "%*s}\n", d->indent, "");
1871 d->indent -= 2;
1874 break;
1876 case TYPE_LANG_STRUCT:
1878 type_p nt;
1879 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1880 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1881 break;
1882 if (nt == NULL)
1883 error_at_line (d->line, "structure `%s' differs between languages",
1884 t->u.s.tag);
1885 else
1886 walk_type (nt, d);
1888 break;
1890 case TYPE_PARAM_STRUCT:
1892 type_p *oldparam = d->param;
1894 d->param = t->u.param_struct.param;
1895 walk_type (t->u.param_struct.stru, d);
1896 d->param = oldparam;
1898 break;
1900 default:
1901 gcc_unreachable ();
1905 /* process_field routine for marking routines. */
1907 static void
1908 write_types_process_field (type_p f, const struct walk_type_data *d)
1910 const struct write_types_data *wtd;
1911 const char *cast = d->needs_cast_p ? "(void *)" : "";
1912 wtd = (const struct write_types_data *) d->cookie;
1914 switch (f->kind)
1916 case TYPE_POINTER:
1917 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1918 wtd->subfield_marker_routine, cast, d->val);
1919 if (wtd->param_prefix)
1921 oprintf (d->of, ", %s", d->prev_val[3]);
1922 if (d->orig_s)
1924 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1925 output_mangled_typename (d->of, d->orig_s);
1927 else
1928 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1930 oprintf (d->of, ");\n");
1931 if (d->reorder_fn && wtd->reorder_note_routine)
1932 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1933 wtd->reorder_note_routine, cast, d->val,
1934 d->prev_val[3], d->reorder_fn);
1935 break;
1937 case TYPE_STRING:
1938 if (wtd->param_prefix == NULL)
1939 break;
1941 case TYPE_STRUCT:
1942 case TYPE_UNION:
1943 case TYPE_LANG_STRUCT:
1944 case TYPE_PARAM_STRUCT:
1945 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1946 output_mangled_typename (d->of, f);
1947 oprintf (d->of, " (%s%s);\n", cast, d->val);
1948 if (d->reorder_fn && wtd->reorder_note_routine)
1949 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1950 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1951 d->reorder_fn);
1952 break;
1954 case TYPE_SCALAR:
1955 break;
1957 default:
1958 gcc_unreachable ();
1962 /* For S, a structure that's part of ORIG_S, and using parameters
1963 PARAM, write out a routine that:
1964 - Takes a parameter, a void * but actually of type *S
1965 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1966 field of S or its substructures and (in some cases) things
1967 that are pointed to by S.
1970 static void
1971 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
1972 const struct write_types_data *wtd)
1974 const char *fn = s->u.s.line.file;
1975 int i;
1976 const char *chain_next = NULL;
1977 const char *chain_prev = NULL;
1978 options_p opt;
1979 struct walk_type_data d;
1981 /* This is a hack, and not the good kind either. */
1982 for (i = NUM_PARAM - 1; i >= 0; i--)
1983 if (param && param[i] && param[i]->kind == TYPE_POINTER
1984 && UNION_OR_STRUCT_P (param[i]->u.p))
1985 fn = param[i]->u.p->u.s.line.file;
1987 memset (&d, 0, sizeof (d));
1988 d.of = get_output_file_with_visibility (fn);
1990 for (opt = s->u.s.opt; opt; opt = opt->next)
1991 if (strcmp (opt->name, "chain_next") == 0)
1992 chain_next = opt->info;
1993 else if (strcmp (opt->name, "chain_prev") == 0)
1994 chain_prev = opt->info;
1996 if (chain_prev != NULL && chain_next == NULL)
1997 error_at_line (&s->u.s.line, "chain_prev without chain_next");
1999 d.process_field = write_types_process_field;
2000 d.cookie = wtd;
2001 d.orig_s = orig_s;
2002 d.opt = s->u.s.opt;
2003 d.line = &s->u.s.line;
2004 d.bitmap = s->u.s.bitmap;
2005 d.param = param;
2006 d.prev_val[0] = "*x";
2007 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2008 d.prev_val[3] = "x";
2009 d.val = "(*x)";
2011 oprintf (d.of, "\n");
2012 oprintf (d.of, "void\n");
2013 if (param == NULL)
2014 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2015 else
2017 oprintf (d.of, "gt_%s_", wtd->prefix);
2018 output_mangled_typename (d.of, orig_s);
2020 oprintf (d.of, " (void *x_p)\n");
2021 oprintf (d.of, "{\n");
2022 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2023 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2024 chain_next == NULL ? "const " : "",
2025 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2026 if (chain_next != NULL)
2027 oprintf (d.of, " %s %s * xlimit = x;\n",
2028 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2029 if (chain_next == NULL)
2031 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2032 if (wtd->param_prefix)
2034 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2035 output_mangled_typename (d.of, orig_s);
2037 oprintf (d.of, "))\n");
2039 else
2041 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2042 if (wtd->param_prefix)
2044 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2045 output_mangled_typename (d.of, orig_s);
2047 oprintf (d.of, "))\n");
2048 oprintf (d.of, " xlimit = (");
2049 d.prev_val[2] = "*xlimit";
2050 output_escaped_param (&d, chain_next, "chain_next");
2051 oprintf (d.of, ");\n");
2052 if (chain_prev != NULL)
2054 oprintf (d.of, " if (x != xlimit)\n");
2055 oprintf (d.of, " for (;;)\n");
2056 oprintf (d.of, " {\n");
2057 oprintf (d.of, " %s %s * const xprev = (",
2058 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2060 d.prev_val[2] = "*x";
2061 output_escaped_param (&d, chain_prev, "chain_prev");
2062 oprintf (d.of, ");\n");
2063 oprintf (d.of, " if (xprev == NULL) break;\n");
2064 oprintf (d.of, " x = xprev;\n");
2065 oprintf (d.of, " (void) %s (xprev",
2066 wtd->marker_routine);
2067 if (wtd->param_prefix)
2069 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2070 output_mangled_typename (d.of, orig_s);
2072 oprintf (d.of, ");\n");
2073 oprintf (d.of, " }\n");
2075 oprintf (d.of, " while (x != xlimit)\n");
2077 oprintf (d.of, " {\n");
2079 d.prev_val[2] = "*x";
2080 d.indent = 6;
2081 walk_type (s, &d);
2083 if (chain_next != NULL)
2085 oprintf (d.of, " x = (");
2086 output_escaped_param (&d, chain_next, "chain_next");
2087 oprintf (d.of, ");\n");
2090 oprintf (d.of, " }\n");
2091 oprintf (d.of, "}\n");
2094 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2096 static void
2097 write_types (type_p structures, type_p param_structs,
2098 const struct write_types_data *wtd)
2100 type_p s;
2102 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2103 for (s = structures; s; s = s->next)
2104 if (s->gc_used == GC_POINTED_TO
2105 || s->gc_used == GC_MAYBE_POINTED_TO)
2107 options_p opt;
2109 if (s->gc_used == GC_MAYBE_POINTED_TO
2110 && s->u.s.line.file == NULL)
2111 continue;
2113 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2114 output_mangled_typename (header_file, s);
2115 oprintf (header_file, "(X) do { \\\n");
2116 oprintf (header_file,
2117 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2118 s->u.s.tag);
2119 oprintf (header_file,
2120 " } while (0)\n");
2122 for (opt = s->u.s.opt; opt; opt = opt->next)
2123 if (strcmp (opt->name, "ptr_alias") == 0)
2125 type_p t = (type_p) opt->info;
2126 if (t->kind == TYPE_STRUCT
2127 || t->kind == TYPE_UNION
2128 || t->kind == TYPE_LANG_STRUCT)
2129 oprintf (header_file,
2130 "#define gt_%sx_%s gt_%sx_%s\n",
2131 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2132 else
2133 error_at_line (&s->u.s.line,
2134 "structure alias is not a structure");
2135 break;
2137 if (opt)
2138 continue;
2140 /* Declare the marker procedure only once. */
2141 oprintf (header_file,
2142 "extern void gt_%sx_%s (void *);\n",
2143 wtd->prefix, s->u.s.tag);
2145 if (s->u.s.line.file == NULL)
2147 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2148 s->u.s.tag);
2149 continue;
2152 if (s->kind == TYPE_LANG_STRUCT)
2154 type_p ss;
2155 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2156 write_func_for_structure (s, ss, NULL, wtd);
2158 else
2159 write_func_for_structure (s, s, NULL, wtd);
2162 for (s = param_structs; s; s = s->next)
2163 if (s->gc_used == GC_POINTED_TO)
2165 type_p * param = s->u.param_struct.param;
2166 type_p stru = s->u.param_struct.stru;
2168 /* Declare the marker procedure. */
2169 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2170 output_mangled_typename (header_file, s);
2171 oprintf (header_file, " (void *);\n");
2173 if (stru->u.s.line.file == NULL)
2175 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2176 s->u.s.tag);
2177 continue;
2180 if (stru->kind == TYPE_LANG_STRUCT)
2182 type_p ss;
2183 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2184 write_func_for_structure (s, ss, param, wtd);
2186 else
2187 write_func_for_structure (s, stru, param, wtd);
2191 static const struct write_types_data ggc_wtd =
2193 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2194 "GC marker procedures. "
2197 static const struct write_types_data pch_wtd =
2199 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2200 "gt_pch_note_reorder",
2201 "PCH type-walking procedures. "
2204 /* Write out the local pointer-walking routines. */
2206 /* process_field routine for local pointer-walking. */
2208 static void
2209 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2211 switch (f->kind)
2213 case TYPE_POINTER:
2214 case TYPE_STRUCT:
2215 case TYPE_UNION:
2216 case TYPE_LANG_STRUCT:
2217 case TYPE_PARAM_STRUCT:
2218 case TYPE_STRING:
2219 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2220 d->prev_val[3]);
2221 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2222 break;
2224 case TYPE_SCALAR:
2225 break;
2227 default:
2228 gcc_unreachable ();
2232 /* For S, a structure that's part of ORIG_S, and using parameters
2233 PARAM, write out a routine that:
2234 - Is of type gt_note_pointers
2235 - Calls PROCESS_FIELD on each field of S or its substructures.
2238 static void
2239 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2241 const char *fn = s->u.s.line.file;
2242 int i;
2243 struct walk_type_data d;
2245 /* This is a hack, and not the good kind either. */
2246 for (i = NUM_PARAM - 1; i >= 0; i--)
2247 if (param && param[i] && param[i]->kind == TYPE_POINTER
2248 && UNION_OR_STRUCT_P (param[i]->u.p))
2249 fn = param[i]->u.p->u.s.line.file;
2251 memset (&d, 0, sizeof (d));
2252 d.of = get_output_file_with_visibility (fn);
2254 d.process_field = write_types_local_process_field;
2255 d.opt = s->u.s.opt;
2256 d.line = &s->u.s.line;
2257 d.bitmap = s->u.s.bitmap;
2258 d.param = param;
2259 d.prev_val[0] = d.prev_val[2] = "*x";
2260 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2261 d.prev_val[3] = "x";
2262 d.val = "(*x)";
2263 d.fn_wants_lvalue = true;
2265 oprintf (d.of, "\n");
2266 oprintf (d.of, "void\n");
2267 oprintf (d.of, "gt_pch_p_");
2268 output_mangled_typename (d.of, orig_s);
2269 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2270 "\tvoid *x_p,\n"
2271 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2272 "\tATTRIBUTE_UNUSED void *cookie)\n");
2273 oprintf (d.of, "{\n");
2274 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2275 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2276 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2277 d.indent = 2;
2278 walk_type (s, &d);
2279 oprintf (d.of, "}\n");
2282 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2284 static void
2285 write_local (type_p structures, type_p param_structs)
2287 type_p s;
2289 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2290 for (s = structures; s; s = s->next)
2291 if (s->gc_used == GC_POINTED_TO
2292 || s->gc_used == GC_MAYBE_POINTED_TO)
2294 options_p opt;
2296 if (s->u.s.line.file == NULL)
2297 continue;
2299 for (opt = s->u.s.opt; opt; opt = opt->next)
2300 if (strcmp (opt->name, "ptr_alias") == 0)
2302 type_p t = (type_p) opt->info;
2303 if (t->kind == TYPE_STRUCT
2304 || t->kind == TYPE_UNION
2305 || t->kind == TYPE_LANG_STRUCT)
2307 oprintf (header_file, "#define gt_pch_p_");
2308 output_mangled_typename (header_file, s);
2309 oprintf (header_file, " gt_pch_p_");
2310 output_mangled_typename (header_file, t);
2311 oprintf (header_file, "\n");
2313 else
2314 error_at_line (&s->u.s.line,
2315 "structure alias is not a structure");
2316 break;
2318 if (opt)
2319 continue;
2321 /* Declare the marker procedure only once. */
2322 oprintf (header_file, "extern void gt_pch_p_");
2323 output_mangled_typename (header_file, s);
2324 oprintf (header_file,
2325 "\n (void *, void *, gt_pointer_operator, void *);\n");
2327 if (s->kind == TYPE_LANG_STRUCT)
2329 type_p ss;
2330 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2331 write_local_func_for_structure (s, ss, NULL);
2333 else
2334 write_local_func_for_structure (s, s, NULL);
2337 for (s = param_structs; s; s = s->next)
2338 if (s->gc_used == GC_POINTED_TO)
2340 type_p * param = s->u.param_struct.param;
2341 type_p stru = s->u.param_struct.stru;
2343 /* Declare the marker procedure. */
2344 oprintf (header_file, "extern void gt_pch_p_");
2345 output_mangled_typename (header_file, s);
2346 oprintf (header_file,
2347 "\n (void *, void *, gt_pointer_operator, void *);\n");
2349 if (stru->u.s.line.file == NULL)
2351 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2352 s->u.s.tag);
2353 continue;
2356 if (stru->kind == TYPE_LANG_STRUCT)
2358 type_p ss;
2359 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2360 write_local_func_for_structure (s, ss, param);
2362 else
2363 write_local_func_for_structure (s, stru, param);
2367 /* Write out the 'enum' definition for gt_types_enum. */
2369 static void
2370 write_enum_defn (type_p structures, type_p param_structs)
2372 type_p s;
2374 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2375 oprintf (header_file, "enum gt_types_enum {\n");
2376 for (s = structures; s; s = s->next)
2377 if (s->gc_used == GC_POINTED_TO
2378 || s->gc_used == GC_MAYBE_POINTED_TO)
2380 if (s->gc_used == GC_MAYBE_POINTED_TO
2381 && s->u.s.line.file == NULL)
2382 continue;
2384 oprintf (header_file, " gt_ggc_e_");
2385 output_mangled_typename (header_file, s);
2386 oprintf (header_file, ", \n");
2388 for (s = param_structs; s; s = s->next)
2389 if (s->gc_used == GC_POINTED_TO)
2391 oprintf (header_file, " gt_e_");
2392 output_mangled_typename (header_file, s);
2393 oprintf (header_file, ", \n");
2395 oprintf (header_file, " gt_types_enum_last\n");
2396 oprintf (header_file, "};\n");
2399 /* Might T contain any non-pointer elements? */
2401 static int
2402 contains_scalar_p (type_p t)
2404 switch (t->kind)
2406 case TYPE_STRING:
2407 case TYPE_POINTER:
2408 return 0;
2409 case TYPE_ARRAY:
2410 return contains_scalar_p (t->u.a.p);
2411 default:
2412 /* Could also check for structures that have no non-pointer
2413 fields, but there aren't enough of those to worry about. */
2414 return 1;
2418 /* Mangle FN and print it to F. */
2420 static void
2421 put_mangled_filename (outf_p f, const char *fn)
2423 const char *name = get_output_file_name (fn);
2424 for (; *name != 0; name++)
2425 if (ISALNUM (*name))
2426 oprintf (f, "%c", *name);
2427 else
2428 oprintf (f, "%c", '_');
2431 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2432 LASTNAME, and NAME are all strings to insert in various places in
2433 the resulting code. */
2435 static void
2436 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2437 const char *tname, const char *name)
2439 struct flist *fli2;
2441 for (fli2 = flp; fli2; fli2 = fli2->next)
2442 if (fli2->started_p)
2444 oprintf (fli2->f, " %s\n", lastname);
2445 oprintf (fli2->f, "};\n\n");
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 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2455 if (bitmap & 1)
2457 oprintf (base_files[fnum],
2458 "extern const struct %s gt_%s_",
2459 tname, 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++)
2468 oprintf (base_files [fnum],
2469 "const struct %s * const %s[] = {\n",
2470 tname, name);
2474 for (fli2 = flp; fli2; fli2 = fli2->next)
2475 if (fli2->started_p)
2477 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2478 int fnum;
2480 fli2->started_p = 0;
2482 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2483 if (bitmap & 1)
2485 oprintf (base_files[fnum], " gt_%s_", pfx);
2486 put_mangled_filename (base_files[fnum], fli2->name);
2487 oprintf (base_files[fnum], ",\n");
2492 size_t fnum;
2493 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2495 oprintf (base_files[fnum], " NULL\n");
2496 oprintf (base_files[fnum], "};\n");
2501 /* Write out to F the table entry and any marker routines needed to
2502 mark NAME as TYPE. The original variable is V, at LINE.
2503 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2504 is nonzero iff we are building the root table for hash table caches. */
2506 static void
2507 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2508 struct fileloc *line, const char *if_marked)
2510 switch (type->kind)
2512 case TYPE_STRUCT:
2514 pair_p fld;
2515 for (fld = type->u.s.fields; fld; fld = fld->next)
2517 int skip_p = 0;
2518 const char *desc = NULL;
2519 options_p o;
2521 for (o = fld->opt; o; o = o->next)
2522 if (strcmp (o->name, "skip") == 0)
2523 skip_p = 1;
2524 else if (strcmp (o->name, "desc") == 0)
2525 desc = o->info;
2526 else
2527 error_at_line (line,
2528 "field `%s' of global `%s' has unknown option `%s'",
2529 fld->name, name, o->name);
2531 if (skip_p)
2532 continue;
2533 else if (desc && fld->type->kind == TYPE_UNION)
2535 pair_p validf = NULL;
2536 pair_p ufld;
2538 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2540 const char *tag = NULL;
2541 options_p oo;
2543 for (oo = ufld->opt; oo; oo = oo->next)
2544 if (strcmp (oo->name, "tag") == 0)
2545 tag = oo->info;
2546 if (tag == NULL || strcmp (tag, desc) != 0)
2547 continue;
2548 if (validf != NULL)
2549 error_at_line (line,
2550 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2551 name, fld->name, validf->name,
2552 name, fld->name, ufld->name,
2553 tag);
2554 validf = ufld;
2556 if (validf != NULL)
2558 char *newname;
2559 newname = xasprintf ("%s.%s.%s",
2560 name, fld->name, validf->name);
2561 write_root (f, v, validf->type, newname, 0, line,
2562 if_marked);
2563 free (newname);
2566 else if (desc)
2567 error_at_line (line,
2568 "global `%s.%s' has `desc' option but is not union",
2569 name, fld->name);
2570 else
2572 char *newname;
2573 newname = xasprintf ("%s.%s", name, fld->name);
2574 write_root (f, v, fld->type, newname, 0, line, if_marked);
2575 free (newname);
2579 break;
2581 case TYPE_ARRAY:
2583 char *newname;
2584 newname = xasprintf ("%s[0]", name);
2585 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2586 free (newname);
2588 break;
2590 case TYPE_POINTER:
2592 type_p ap, tp;
2594 oprintf (f, " {\n");
2595 oprintf (f, " &%s,\n", name);
2596 oprintf (f, " 1");
2598 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2599 if (ap->u.a.len[0])
2600 oprintf (f, " * (%s)", ap->u.a.len);
2601 else if (ap == v->type)
2602 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2603 oprintf (f, ",\n");
2604 oprintf (f, " sizeof (%s", v->name);
2605 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2606 oprintf (f, "[0]");
2607 oprintf (f, "),\n");
2609 tp = type->u.p;
2611 if (! has_length && UNION_OR_STRUCT_P (tp))
2613 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2614 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2616 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2618 oprintf (f, " &gt_ggc_m_");
2619 output_mangled_typename (f, tp);
2620 oprintf (f, ",\n &gt_pch_n_");
2621 output_mangled_typename (f, tp);
2623 else if (has_length
2624 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2626 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2627 oprintf (f, " &gt_pch_na_%s", name);
2629 else
2631 error_at_line (line,
2632 "global `%s' is pointer to unimplemented type",
2633 name);
2635 if (if_marked)
2636 oprintf (f, ",\n &%s", if_marked);
2637 oprintf (f, "\n },\n");
2639 break;
2641 case TYPE_STRING:
2643 oprintf (f, " {\n");
2644 oprintf (f, " &%s,\n", name);
2645 oprintf (f, " 1, \n");
2646 oprintf (f, " sizeof (%s),\n", v->name);
2647 oprintf (f, " &gt_ggc_m_S,\n");
2648 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2649 oprintf (f, " },\n");
2651 break;
2653 case TYPE_SCALAR:
2654 break;
2656 default:
2657 error_at_line (line,
2658 "global `%s' is unimplemented type",
2659 name);
2663 /* This generates a routine to walk an array. */
2665 static void
2666 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2668 struct walk_type_data d;
2669 char *prevval3;
2671 memset (&d, 0, sizeof (d));
2672 d.of = f;
2673 d.cookie = wtd;
2674 d.indent = 2;
2675 d.line = &v->line;
2676 d.opt = v->opt;
2677 d.bitmap = get_base_file_bitmap (v->line.file);
2678 d.param = NULL;
2680 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2682 if (wtd->param_prefix)
2684 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2685 oprintf (f,
2686 " (void *, void *, gt_pointer_operator, void *);\n");
2687 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2688 wtd->param_prefix, v->name);
2689 oprintf (d.of,
2690 " ATTRIBUTE_UNUSED void *x_p,\n"
2691 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2692 " ATTRIBUTE_UNUSED void * cookie)\n");
2693 oprintf (d.of, "{\n");
2694 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2695 d.process_field = write_types_local_process_field;
2696 walk_type (v->type, &d);
2697 oprintf (f, "}\n\n");
2700 d.opt = v->opt;
2701 oprintf (f, "static void gt_%sa_%s (void *);\n",
2702 wtd->prefix, v->name);
2703 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2704 wtd->prefix, v->name);
2705 oprintf (f, "{\n");
2706 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2707 d.process_field = write_types_process_field;
2708 walk_type (v->type, &d);
2709 free (prevval3);
2710 oprintf (f, "}\n\n");
2713 /* Output a table describing the locations and types of VARIABLES. */
2715 static void
2716 write_roots (pair_p variables)
2718 pair_p v;
2719 struct flist *flp = NULL;
2721 for (v = variables; v; v = v->next)
2723 outf_p f = get_output_file_with_visibility (v->line.file);
2724 struct flist *fli;
2725 const char *length = NULL;
2726 int deletable_p = 0;
2727 options_p o;
2729 for (o = v->opt; o; o = o->next)
2730 if (strcmp (o->name, "length") == 0)
2731 length = o->info;
2732 else if (strcmp (o->name, "deletable") == 0)
2733 deletable_p = 1;
2734 else if (strcmp (o->name, "param_is") == 0)
2736 else if (strncmp (o->name, "param", 5) == 0
2737 && ISDIGIT (o->name[5])
2738 && strcmp (o->name + 6, "_is") == 0)
2740 else if (strcmp (o->name, "if_marked") == 0)
2742 else
2743 error_at_line (&v->line,
2744 "global `%s' has unknown option `%s'",
2745 v->name, o->name);
2747 for (fli = flp; fli; fli = fli->next)
2748 if (fli->f == f)
2749 break;
2750 if (fli == NULL)
2752 fli = XNEW (struct flist);
2753 fli->f = f;
2754 fli->next = flp;
2755 fli->started_p = 0;
2756 fli->name = v->line.file;
2757 flp = fli;
2759 oprintf (f, "\n/* GC roots. */\n\n");
2762 if (! deletable_p
2763 && length
2764 && v->type->kind == TYPE_POINTER
2765 && (v->type->u.p->kind == TYPE_POINTER
2766 || v->type->u.p->kind == TYPE_STRUCT))
2768 write_array (f, v, &ggc_wtd);
2769 write_array (f, v, &pch_wtd);
2773 for (v = variables; v; v = v->next)
2775 outf_p f = get_output_file_with_visibility (v->line.file);
2776 struct flist *fli;
2777 int skip_p = 0;
2778 int length_p = 0;
2779 options_p o;
2781 for (o = v->opt; o; o = o->next)
2782 if (strcmp (o->name, "length") == 0)
2783 length_p = 1;
2784 else if (strcmp (o->name, "deletable") == 0
2785 || strcmp (o->name, "if_marked") == 0)
2786 skip_p = 1;
2788 if (skip_p)
2789 continue;
2791 for (fli = flp; fli; fli = fli->next)
2792 if (fli->f == f)
2793 break;
2794 if (! fli->started_p)
2796 fli->started_p = 1;
2798 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2799 put_mangled_filename (f, v->line.file);
2800 oprintf (f, "[] = {\n");
2803 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2806 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2807 "gt_ggc_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 int skip_p = 1;
2814 options_p o;
2816 for (o = v->opt; o; o = o->next)
2817 if (strcmp (o->name, "deletable") == 0)
2818 skip_p = 0;
2819 else if (strcmp (o->name, "if_marked") == 0)
2820 skip_p = 1;
2822 if (skip_p)
2823 continue;
2825 for (fli = flp; fli; fli = fli->next)
2826 if (fli->f == f)
2827 break;
2828 if (! fli->started_p)
2830 fli->started_p = 1;
2832 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2833 put_mangled_filename (f, v->line.file);
2834 oprintf (f, "[] = {\n");
2837 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2838 v->name, v->name);
2841 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2842 "gt_ggc_deletable_rtab");
2844 for (v = variables; v; v = v->next)
2846 outf_p f = get_output_file_with_visibility (v->line.file);
2847 struct flist *fli;
2848 const char *if_marked = NULL;
2849 int length_p = 0;
2850 options_p o;
2852 for (o = v->opt; o; o = o->next)
2853 if (strcmp (o->name, "length") == 0)
2854 length_p = 1;
2855 else if (strcmp (o->name, "if_marked") == 0)
2856 if_marked = o->info;
2858 if (if_marked == NULL)
2859 continue;
2861 if (v->type->kind != TYPE_POINTER
2862 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2863 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2865 error_at_line (&v->line, "if_marked option used but not hash table");
2866 continue;
2869 for (fli = flp; fli; fli = fli->next)
2870 if (fli->f == f)
2871 break;
2872 if (! fli->started_p)
2874 fli->started_p = 1;
2876 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2877 put_mangled_filename (f, v->line.file);
2878 oprintf (f, "[] = {\n");
2881 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2882 v->name, length_p, &v->line, if_marked);
2885 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2886 "gt_ggc_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 length_p = 0;
2893 int if_marked_p = 0;
2894 options_p o;
2896 for (o = v->opt; o; o = o->next)
2897 if (strcmp (o->name, "length") == 0)
2898 length_p = 1;
2899 else if (strcmp (o->name, "if_marked") == 0)
2900 if_marked_p = 1;
2902 if (! if_marked_p)
2903 continue;
2905 for (fli = flp; fli; fli = fli->next)
2906 if (fli->f == f)
2907 break;
2908 if (! fli->started_p)
2910 fli->started_p = 1;
2912 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2913 put_mangled_filename (f, v->line.file);
2914 oprintf (f, "[] = {\n");
2917 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2920 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2921 "gt_pch_cache_rtab");
2923 for (v = variables; v; v = v->next)
2925 outf_p f = get_output_file_with_visibility (v->line.file);
2926 struct flist *fli;
2927 int skip_p = 0;
2928 options_p o;
2930 for (o = v->opt; o; o = o->next)
2931 if (strcmp (o->name, "deletable") == 0
2932 || strcmp (o->name, "if_marked") == 0)
2933 skip_p = 1;
2935 if (skip_p)
2936 continue;
2938 if (! contains_scalar_p (v->type))
2939 continue;
2941 for (fli = flp; fli; fli = fli->next)
2942 if (fli->f == f)
2943 break;
2944 if (! fli->started_p)
2946 fli->started_p = 1;
2948 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2949 put_mangled_filename (f, v->line.file);
2950 oprintf (f, "[] = {\n");
2953 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2954 v->name, v->name);
2957 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2958 "gt_pch_scalar_rtab");
2962 extern int main (int argc, char **argv);
2964 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
2966 unsigned i;
2967 static struct fileloc pos = { __FILE__, __LINE__ };
2968 unsigned j;
2970 gen_rtx_next ();
2972 srcdir_len = strlen (srcdir);
2974 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
2975 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
2976 do_scalar_typedef ("uint8", &pos);
2977 do_scalar_typedef ("jword", &pos);
2978 do_scalar_typedef ("JCF_u2", &pos);
2979 #ifdef USE_MAPPED_LOCATION
2980 do_scalar_typedef ("location_t", &pos);
2981 do_scalar_typedef ("source_locus", &pos);
2982 #endif
2983 do_scalar_typedef ("void", &pos);
2985 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
2987 do_typedef ("HARD_REG_SET", create_array (
2988 create_scalar_type ("unsigned long", strlen ("unsigned long")),
2989 "2"), &pos);
2991 for (i = 0; i < NUM_GT_FILES; i++)
2993 int dupflag = 0;
2994 /* Omit if already seen. */
2995 for (j = 0; j < i; j++)
2997 if (!strcmp (all_files[i], all_files[j]))
2999 dupflag = 1;
3000 break;
3003 if (!dupflag)
3004 parse_file (all_files[i]);
3005 #ifndef USE_MAPPED_LOCATION
3006 /* temporary kludge - gengtype doesn't handle conditionals.
3007 Manually add source_locus *after* we've processed input.h. */
3008 if (i == 0)
3009 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3010 #endif
3013 if (hit_error != 0)
3014 exit (1);
3016 set_gc_used (variables);
3018 open_base_files ();
3019 write_enum_defn (structures, param_structs);
3020 write_types (structures, param_structs, &ggc_wtd);
3021 write_types (structures, param_structs, &pch_wtd);
3022 write_local (structures, param_structs);
3023 write_roots (variables);
3024 write_rtx_next ();
3025 close_output_files ();
3027 return (hit_error != 0);