Add an UNSPEC_PROLOGUE_USE to prevent the link register from being considered dead.
[official-gcc.git] / gcc / gengtype.c
blobcbaf7ac6d67b2f87769f096dd53049306156955c
1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003 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"
28 /* Nonzero iff an error has occurred. */
29 static int hit_error = 0;
31 static void gen_rtx_next PARAMS ((void));
32 static void write_rtx_next PARAMS ((void));
33 static void open_base_files PARAMS ((void));
34 static void close_output_files PARAMS ((void));
36 /* Report an error at POS, printing MSG. */
38 void
39 error_at_line VPARAMS ((struct fileloc *pos, const char *msg, ...))
41 VA_OPEN (ap, msg);
42 VA_FIXEDARG (ap, struct fileloc *, pos);
43 VA_FIXEDARG (ap, const char *, msg);
45 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
46 vfprintf (stderr, msg, ap);
47 fputc ('\n', stderr);
48 hit_error = 1;
50 VA_CLOSE (ap);
53 /* vasprintf, but produces fatal message on out-of-memory. */
54 int
55 xvasprintf (result, format, args)
56 char ** result;
57 const char *format;
58 va_list args;
60 int ret = vasprintf (result, format, args);
61 if (*result == NULL || ret < 0)
63 fputs ("gengtype: out of memory", stderr);
64 xexit (1);
66 return ret;
69 /* Wrapper for xvasprintf. */
70 char *
71 xasprintf VPARAMS ((const char *format, ...))
73 char *result;
74 VA_OPEN (ap, format);
75 VA_FIXEDARG (ap, const char *, format);
76 xvasprintf (&result, format, ap);
77 VA_CLOSE (ap);
78 return result;
81 /* The one and only TYPE_STRING. */
83 struct type string_type = {
84 TYPE_STRING, NULL, NULL, GC_USED
85 UNION_INIT_ZERO
86 };
88 /* Lists of various things. */
90 static pair_p typedefs;
91 static type_p structures;
92 static type_p param_structs;
93 static pair_p variables;
95 static void do_scalar_typedef PARAMS ((const char *, struct fileloc *));
96 static type_p find_param_structure
97 PARAMS ((type_p t, type_p param[NUM_PARAM]));
98 static type_p adjust_field_tree_exp PARAMS ((type_p t, options_p opt));
99 static type_p adjust_field_rtx_def PARAMS ((type_p t, options_p opt));
101 /* Define S as a typedef to T at POS. */
103 void
104 do_typedef (s, t, pos)
105 const char *s;
106 type_p t;
107 struct fileloc *pos;
109 pair_p p;
111 for (p = typedefs; p != NULL; p = p->next)
112 if (strcmp (p->name, s) == 0)
114 if (p->type != t)
116 error_at_line (pos, "type `%s' previously defined", s);
117 error_at_line (&p->line, "previously defined here");
119 return;
122 p = xmalloc (sizeof (struct pair));
123 p->next = typedefs;
124 p->name = s;
125 p->type = t;
126 p->line = *pos;
127 typedefs = p;
130 /* Define S as a typename of a scalar. */
132 static void
133 do_scalar_typedef (s, pos)
134 const char *s;
135 struct fileloc *pos;
137 do_typedef (s, create_scalar_type (s, strlen (s)), pos);
140 /* Return the type previously defined for S. Use POS to report errors. */
142 type_p
143 resolve_typedef (s, pos)
144 const char *s;
145 struct fileloc *pos;
147 pair_p p;
148 for (p = typedefs; p != NULL; p = p->next)
149 if (strcmp (p->name, s) == 0)
150 return p->type;
151 error_at_line (pos, "unidentified type `%s'", s);
152 return create_scalar_type ("char", 4);
155 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
156 at POS with fields FIELDS and options O. */
158 void
159 new_structure (name, isunion, pos, fields, o)
160 const char *name;
161 int isunion;
162 struct fileloc *pos;
163 pair_p fields;
164 options_p o;
166 type_p si;
167 type_p s = NULL;
168 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
170 for (si = structures; si != NULL; si = si->next)
171 if (strcmp (name, si->u.s.tag) == 0
172 && UNION_P (si) == isunion)
174 type_p ls = NULL;
175 if (si->kind == TYPE_LANG_STRUCT)
177 ls = si;
179 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
180 if (si->u.s.bitmap == bitmap)
181 s = si;
183 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
185 ls = si;
186 si = xcalloc (1, sizeof (struct type));
187 memcpy (si, ls, sizeof (struct type));
188 ls->kind = TYPE_LANG_STRUCT;
189 ls->u.s.lang_struct = si;
190 ls->u.s.fields = NULL;
191 si->next = NULL;
192 si->pointer_to = NULL;
193 si->u.s.lang_struct = ls;
195 else
196 s = si;
198 if (ls != NULL && s == NULL)
200 s = xcalloc (1, sizeof (struct type));
201 s->next = ls->u.s.lang_struct;
202 ls->u.s.lang_struct = s;
203 s->u.s.lang_struct = ls;
205 break;
208 if (s == NULL)
210 s = xcalloc (1, sizeof (struct type));
211 s->next = structures;
212 structures = s;
215 if (s->u.s.line.file != NULL
216 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
218 error_at_line (pos, "duplicate structure definition");
219 error_at_line (&s->u.s.line, "previous definition here");
222 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
223 s->u.s.tag = name;
224 s->u.s.line = *pos;
225 s->u.s.fields = fields;
226 s->u.s.opt = o;
227 s->u.s.bitmap = bitmap;
228 if (s->u.s.lang_struct)
229 s->u.s.lang_struct->u.s.bitmap |= bitmap;
232 /* Return the previously-defined structure with tag NAME (or a union
233 iff ISUNION is nonzero), or a new empty structure or union if none
234 was defined previously. */
236 type_p
237 find_structure (name, isunion)
238 const char *name;
239 int isunion;
241 type_p s;
243 for (s = structures; s != NULL; s = s->next)
244 if (strcmp (name, s->u.s.tag) == 0
245 && UNION_P (s) == isunion)
246 return s;
248 s = xcalloc (1, sizeof (struct type));
249 s->next = structures;
250 structures = s;
251 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
252 s->u.s.tag = name;
253 structures = s;
254 return s;
257 /* Return the previously-defined parameterized structure for structure
258 T and parameters PARAM, or a new parameterized empty structure or
259 union if none was defined previously. */
261 static type_p
262 find_param_structure (t, param)
263 type_p t;
264 type_p param[NUM_PARAM];
266 type_p res;
268 for (res = param_structs; res; res = res->next)
269 if (res->u.param_struct.stru == t
270 && memcmp (res->u.param_struct.param, param,
271 sizeof (type_p) * NUM_PARAM) == 0)
272 break;
273 if (res == NULL)
275 res = xcalloc (1, sizeof (*res));
276 res->kind = TYPE_PARAM_STRUCT;
277 res->next = param_structs;
278 param_structs = res;
279 res->u.param_struct.stru = t;
280 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
282 return res;
285 /* Return a scalar type with name NAME. */
287 type_p
288 create_scalar_type (name, name_len)
289 const char *name;
290 size_t name_len;
292 type_p r = xcalloc (1, sizeof (struct type));
293 r->kind = TYPE_SCALAR;
294 r->u.sc = xmemdup (name, name_len, name_len + 1);
295 return r;
298 /* Return a pointer to T. */
300 type_p
301 create_pointer (t)
302 type_p t;
304 if (! t->pointer_to)
306 type_p r = xcalloc (1, sizeof (struct type));
307 r->kind = TYPE_POINTER;
308 r->u.p = t;
309 t->pointer_to = r;
311 return t->pointer_to;
314 /* Return an array of length LEN. */
316 type_p
317 create_array (t, len)
318 type_p t;
319 const char *len;
321 type_p v;
323 v = xcalloc (1, sizeof (*v));
324 v->kind = TYPE_ARRAY;
325 v->u.a.p = t;
326 v->u.a.len = len;
327 return v;
330 /* Add a variable named S of type T with options O defined at POS,
331 to `variables'. */
333 void
334 note_variable (s, t, o, pos)
335 const char *s;
336 type_p t;
337 options_p o;
338 struct fileloc *pos;
340 pair_p n;
341 n = xmalloc (sizeof (*n));
342 n->name = s;
343 n->type = t;
344 n->line = *pos;
345 n->opt = o;
346 n->next = variables;
347 variables = n;
350 enum rtx_code {
351 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
352 #include "rtl.def"
353 #undef DEF_RTL_EXPR
354 NUM_RTX_CODE
357 /* We really don't care how long a CONST_DOUBLE is. */
358 #define CONST_DOUBLE_FORMAT "ww"
359 static const char * const rtx_format[NUM_RTX_CODE] = {
360 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
361 #include "rtl.def"
362 #undef DEF_RTL_EXPR
365 static int rtx_next[NUM_RTX_CODE];
367 /* Generate the contents of the rtx_next array. This really doesn't belong
368 in gengtype at all, but it's needed for adjust_field_rtx_def. */
370 static void
371 gen_rtx_next ()
373 int i;
374 for (i = 0; i < NUM_RTX_CODE; i++)
376 int k;
378 rtx_next[i] = -1;
379 if (strncmp (rtx_format[i], "iuu", 3) == 0)
380 rtx_next[i] = 2;
381 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
382 rtx_next[i] = 1;
383 else
384 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
385 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
386 rtx_next[i] = k;
390 /* Write out the contents of the rtx_next array. */
391 static void
392 write_rtx_next ()
394 outf_p f = get_output_file_with_visibility (NULL);
395 int i;
397 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
398 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
399 for (i = 0; i < NUM_RTX_CODE; i++)
400 if (rtx_next[i] == -1)
401 oprintf (f, " 0,\n");
402 else
403 oprintf (f,
404 " offsetof (struct rtx_def, fld) + %d * sizeof (rtunion),\n",
405 rtx_next[i]);
406 oprintf (f, "};\n");
409 /* Handle `special("rtx_def")'. This is a special case for field
410 `fld' of struct rtx_def, which is an array of unions whose values
411 are based in a complex way on the type of RTL. */
413 static type_p
414 adjust_field_rtx_def (t, opt)
415 type_p t;
416 options_p opt ATTRIBUTE_UNUSED;
418 pair_p flds = NULL;
419 options_p nodot;
420 int i;
421 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
422 type_p bitmap_tp, basic_block_tp;
424 static const char * const rtx_name[NUM_RTX_CODE] = {
425 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
426 #include "rtl.def"
427 #undef DEF_RTL_EXPR
430 if (t->kind != TYPE_ARRAY)
432 error_at_line (&lexer_line,
433 "special `rtx_def' must be applied to an array");
434 return &string_type;
437 nodot = xmalloc (sizeof (*nodot));
438 nodot->next = NULL;
439 nodot->name = "dot";
440 nodot->info = "";
442 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
443 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
444 tree_tp = create_pointer (find_structure ("tree_node", 1));
445 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
446 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
447 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
448 scalar_tp = create_scalar_type ("rtunion scalar", 14);
451 pair_p note_flds = NULL;
452 int c;
454 for (c = 0; c < 3; c++)
456 pair_p old_note_flds = note_flds;
458 note_flds = xmalloc (sizeof (*note_flds));
459 note_flds->line.file = __FILE__;
460 note_flds->line.line = __LINE__;
461 note_flds->name = "rttree";
462 note_flds->type = tree_tp;
463 note_flds->opt = xmalloc (sizeof (*note_flds->opt));
464 note_flds->opt->next = nodot;
465 note_flds->opt->name = "tag";
466 note_flds->next = old_note_flds;
469 note_flds->type = rtx_tp;
470 note_flds->name = "rtx";
471 note_flds->opt->info = "NOTE_INSN_EXPECTED_VALUE";
472 note_flds->next->opt->info = "NOTE_INSN_BLOCK_BEG";
473 note_flds->next->next->opt->info = "NOTE_INSN_BLOCK_END";
475 new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL);
478 note_union_tp = find_structure ("rtx_def_note_subunion", 1);
480 for (i = 0; i < NUM_RTX_CODE; i++)
482 pair_p old_flds = flds;
483 pair_p subfields = NULL;
484 size_t aindex, nmindex;
485 const char *sname;
486 char *ftag;
488 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
490 pair_p old_subf = subfields;
491 type_p t;
492 const char *subname;
494 switch (rtx_format[i][aindex])
496 case '*':
497 case 'i':
498 case 'n':
499 case 'w':
500 t = scalar_tp;
501 subname = "rtint";
502 break;
504 case '0':
505 if (i == MEM && aindex == 1)
506 t = mem_attrs_tp, subname = "rtmem";
507 else if (i == JUMP_INSN && aindex == 9)
508 t = rtx_tp, subname = "rtx";
509 else if (i == CODE_LABEL && aindex == 4)
510 t = scalar_tp, subname = "rtint";
511 else if (i == CODE_LABEL && aindex == 5)
512 t = rtx_tp, subname = "rtx";
513 else if (i == LABEL_REF
514 && (aindex == 1 || aindex == 2))
515 t = rtx_tp, subname = "rtx";
516 else if (i == NOTE && aindex == 4)
517 t = note_union_tp, subname = "";
518 else if (i == NOTE && aindex >= 7)
519 t = scalar_tp, subname = "rtint";
520 else if (i == ADDR_DIFF_VEC && aindex == 4)
521 t = scalar_tp, subname = "rtint";
522 else if (i == VALUE && aindex == 0)
523 t = scalar_tp, subname = "rtint";
524 else if (i == REG && aindex == 1)
525 t = scalar_tp, subname = "rtint";
526 else if (i == SCRATCH && aindex == 0)
527 t = scalar_tp, subname = "rtint";
528 else if (i == BARRIER && aindex >= 3)
529 t = scalar_tp, subname = "rtint";
530 else
532 error_at_line (&lexer_line,
533 "rtx type `%s' has `0' in position %lu, can't handle",
534 rtx_name[i], (unsigned long) aindex);
535 t = &string_type;
536 subname = "rtint";
538 break;
540 case 's':
541 case 'S':
542 case 'T':
543 t = &string_type;
544 subname = "rtstr";
545 break;
547 case 'e':
548 case 'u':
549 t = rtx_tp;
550 subname = "rtx";
551 break;
553 case 'E':
554 case 'V':
555 t = rtvec_tp;
556 subname = "rtvec";
557 break;
559 case 't':
560 t = tree_tp;
561 subname = "rttree";
562 break;
564 case 'b':
565 t = bitmap_tp;
566 subname = "rtbit";
567 break;
569 case 'B':
570 t = basic_block_tp;
571 subname = "bb";
572 break;
574 default:
575 error_at_line (&lexer_line,
576 "rtx type `%s' has `%c' in position %lu, can't handle",
577 rtx_name[i], rtx_format[i][aindex],
578 (unsigned long)aindex);
579 t = &string_type;
580 subname = "rtint";
581 break;
584 subfields = xmalloc (sizeof (*subfields));
585 subfields->next = old_subf;
586 subfields->type = t;
587 subfields->name = xasprintf ("[%lu].%s", (unsigned long)aindex,
588 subname);
589 subfields->line.file = __FILE__;
590 subfields->line.line = __LINE__;
591 if (t == note_union_tp)
593 subfields->opt = xmalloc (sizeof (*subfields->opt));
594 subfields->opt->next = nodot;
595 subfields->opt->name = "desc";
596 subfields->opt->info = "NOTE_LINE_NUMBER (&%0)";
598 else if (t == basic_block_tp)
600 /* We don't presently GC basic block structures... */
601 subfields->opt = xmalloc (sizeof (*subfields->opt));
602 subfields->opt->next = nodot;
603 subfields->opt->name = "skip";
604 subfields->opt->info = NULL;
606 else
607 subfields->opt = nodot;
610 flds = xmalloc (sizeof (*flds));
611 flds->next = old_flds;
612 flds->name = "";
613 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
614 new_structure (sname, 0, &lexer_line, subfields, NULL);
615 flds->type = find_structure (sname, 0);
616 flds->line.file = __FILE__;
617 flds->line.line = __LINE__;
618 flds->opt = xmalloc (sizeof (*flds->opt));
619 flds->opt->next = nodot;
620 flds->opt->name = "tag";
621 ftag = xstrdup (rtx_name[i]);
622 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
623 ftag[nmindex] = TOUPPER (ftag[nmindex]);
624 flds->opt->info = ftag;
627 new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
628 return find_structure ("rtx_def_subunion", 1);
631 /* Handle `special("tree_exp")'. This is a special case for
632 field `operands' of struct tree_exp, which although it claims to contain
633 pointers to trees, actually sometimes contains pointers to RTL too.
634 Passed T, the old type of the field, and OPT its options. Returns
635 a new type for the field. */
637 static type_p
638 adjust_field_tree_exp (t, opt)
639 type_p t;
640 options_p opt ATTRIBUTE_UNUSED;
642 pair_p flds;
643 options_p nodot;
644 size_t i;
645 static const struct {
646 const char *name;
647 int first_rtl;
648 int num_rtl;
649 } data[] = {
650 { "SAVE_EXPR", 2, 1 },
651 { "GOTO_SUBROUTINE_EXPR", 0, 2 },
652 { "RTL_EXPR", 0, 2 },
653 { "WITH_CLEANUP_EXPR", 2, 1 },
654 { "METHOD_CALL_EXPR", 3, 1 }
657 if (t->kind != TYPE_ARRAY)
659 error_at_line (&lexer_line,
660 "special `tree_exp' must be applied to an array");
661 return &string_type;
664 nodot = xmalloc (sizeof (*nodot));
665 nodot->next = NULL;
666 nodot->name = "dot";
667 nodot->info = "";
669 flds = xmalloc (sizeof (*flds));
670 flds->next = NULL;
671 flds->name = "";
672 flds->type = t;
673 flds->line.file = __FILE__;
674 flds->line.line = __LINE__;
675 flds->opt = xmalloc (sizeof (*flds->opt));
676 flds->opt->next = nodot;
677 flds->opt->name = "length";
678 flds->opt->info = "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
680 options_p oldopt = flds->opt;
681 flds->opt = xmalloc (sizeof (*flds->opt));
682 flds->opt->next = oldopt;
683 flds->opt->name = "default";
684 flds->opt->info = "";
687 for (i = 0; i < ARRAY_SIZE (data); i++)
689 pair_p old_flds = flds;
690 pair_p subfields = NULL;
691 int r_index;
692 const char *sname;
694 for (r_index = 0;
695 r_index < data[i].first_rtl + data[i].num_rtl;
696 r_index++)
698 pair_p old_subf = subfields;
699 subfields = xmalloc (sizeof (*subfields));
700 subfields->next = old_subf;
701 subfields->name = xasprintf ("[%d]", r_index);
702 if (r_index < data[i].first_rtl)
703 subfields->type = t->u.a.p;
704 else
705 subfields->type = create_pointer (find_structure ("rtx_def", 0));
706 subfields->line.file = __FILE__;
707 subfields->line.line = __LINE__;
708 subfields->opt = nodot;
711 flds = xmalloc (sizeof (*flds));
712 flds->next = old_flds;
713 flds->name = "";
714 sname = xasprintf ("tree_exp_%s", data[i].name);
715 new_structure (sname, 0, &lexer_line, subfields, NULL);
716 flds->type = find_structure (sname, 0);
717 flds->line.file = __FILE__;
718 flds->line.line = __LINE__;
719 flds->opt = xmalloc (sizeof (*flds->opt));
720 flds->opt->next = nodot;
721 flds->opt->name = "tag";
722 flds->opt->info = data[i].name;
725 new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
726 return find_structure ("tree_exp_subunion", 1);
729 /* Perform any special processing on a type T, about to become the type
730 of a field. Return the appropriate type for the field.
731 At present:
732 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
733 - Similarly for arrays of pointer-to-char;
734 - Converts structures for which a parameter is provided to
735 TYPE_PARAM_STRUCT;
736 - Handles "special" options.
739 type_p
740 adjust_field_type (t, opt)
741 type_p t;
742 options_p opt;
744 int length_p = 0;
745 const int pointer_p = t->kind == TYPE_POINTER;
746 type_p params[NUM_PARAM];
747 int params_p = 0;
748 int i;
750 for (i = 0; i < NUM_PARAM; i++)
751 params[i] = NULL;
753 for (; opt; opt = opt->next)
754 if (strcmp (opt->name, "length") == 0)
755 length_p = 1;
756 else if (strcmp (opt->name, "param_is") == 0
757 || (strncmp (opt->name, "param", 5) == 0
758 && ISDIGIT (opt->name[5])
759 && strcmp (opt->name + 6, "_is") == 0))
761 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
763 if (! UNION_OR_STRUCT_P (t)
764 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
766 error_at_line (&lexer_line,
767 "option `%s' may only be applied to structures or structure pointers",
768 opt->name);
769 return t;
772 params_p = 1;
773 if (params[num] != NULL)
774 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
775 if (! ISDIGIT (opt->name[5]))
776 params[num] = create_pointer ((type_p) opt->info);
777 else
778 params[num] = (type_p) opt->info;
780 else if (strcmp (opt->name, "special") == 0)
782 const char *special_name = (const char *)opt->info;
783 if (strcmp (special_name, "tree_exp") == 0)
784 t = adjust_field_tree_exp (t, opt);
785 else if (strcmp (special_name, "rtx_def") == 0)
786 t = adjust_field_rtx_def (t, opt);
787 else
788 error_at_line (&lexer_line, "unknown special `%s'", special_name);
791 if (params_p)
793 type_p realt;
795 if (pointer_p)
796 t = t->u.p;
797 realt = find_param_structure (t, params);
798 t = pointer_p ? create_pointer (realt) : realt;
801 if (! length_p
802 && pointer_p
803 && t->u.p->kind == TYPE_SCALAR
804 && (strcmp (t->u.p->u.sc, "char") == 0
805 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
806 return &string_type;
807 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
808 && t->u.a.p->u.p->kind == TYPE_SCALAR
809 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
810 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
811 return create_array (&string_type, t->u.a.len);
813 return t;
816 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
817 and information about the correspondence between token types and fields
818 in TYPEINFO. POS is used for error messages. */
820 void
821 note_yacc_type (o, fields, typeinfo, pos)
822 options_p o;
823 pair_p fields;
824 pair_p typeinfo;
825 struct fileloc *pos;
827 pair_p p;
828 pair_p *p_p;
830 for (p = typeinfo; p; p = p->next)
832 pair_p m;
834 if (p->name == NULL)
835 continue;
837 if (p->type == (type_p) 1)
839 pair_p pp;
840 int ok = 0;
842 for (pp = typeinfo; pp; pp = pp->next)
843 if (pp->type != (type_p) 1
844 && strcmp (pp->opt->info, p->opt->info) == 0)
846 ok = 1;
847 break;
849 if (! ok)
850 continue;
853 for (m = fields; m; m = m->next)
854 if (strcmp (m->name, p->name) == 0)
855 p->type = m->type;
856 if (p->type == NULL)
858 error_at_line (&p->line,
859 "couldn't match fieldname `%s'", p->name);
860 p->name = NULL;
864 p_p = &typeinfo;
865 while (*p_p)
867 pair_p p = *p_p;
869 if (p->name == NULL
870 || p->type == (type_p) 1)
871 *p_p = p->next;
872 else
873 p_p = &p->next;
876 new_structure ("yy_union", 1, pos, typeinfo, o);
877 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
880 static void process_gc_options PARAMS ((options_p, enum gc_used_enum,
881 int *, int *, int *));
882 static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum, type_p *));
883 static void set_gc_used PARAMS ((pair_p));
885 /* Handle OPT for set_gc_used_type. */
887 static void
888 process_gc_options (opt, level, maybe_undef, pass_param, length)
889 options_p opt;
890 enum gc_used_enum level;
891 int *maybe_undef;
892 int *pass_param;
893 int *length;
895 options_p o;
896 for (o = opt; o; o = o->next)
897 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
898 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
899 else if (strcmp (o->name, "maybe_undef") == 0)
900 *maybe_undef = 1;
901 else if (strcmp (o->name, "use_params") == 0)
902 *pass_param = 1;
903 else if (strcmp (o->name, "length") == 0)
904 *length = 1;
907 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
909 static void
910 set_gc_used_type (t, level, param)
911 type_p t;
912 enum gc_used_enum level;
913 type_p param[NUM_PARAM];
915 if (t->gc_used >= level)
916 return;
918 t->gc_used = level;
920 switch (t->kind)
922 case TYPE_STRUCT:
923 case TYPE_UNION:
925 pair_p f;
926 int dummy;
928 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy);
930 for (f = t->u.s.fields; f; f = f->next)
932 int maybe_undef = 0;
933 int pass_param = 0;
934 int length = 0;
935 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
936 &length);
938 if (length && f->type->kind == TYPE_POINTER)
939 set_gc_used_type (f->type->u.p, GC_USED, NULL);
940 else if (maybe_undef && f->type->kind == TYPE_POINTER)
941 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
942 else if (pass_param && f->type->kind == TYPE_POINTER && param)
943 set_gc_used_type (find_param_structure (f->type->u.p, param),
944 GC_POINTED_TO, NULL);
945 else
946 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
948 break;
951 case TYPE_POINTER:
952 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
953 break;
955 case TYPE_ARRAY:
956 set_gc_used_type (t->u.a.p, GC_USED, param);
957 break;
959 case TYPE_LANG_STRUCT:
960 for (t = t->u.s.lang_struct; t; t = t->next)
961 set_gc_used_type (t, level, param);
962 break;
964 case TYPE_PARAM_STRUCT:
966 int i;
967 for (i = 0; i < NUM_PARAM; i++)
968 if (t->u.param_struct.param[i] != 0)
969 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
971 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
972 level = GC_POINTED_TO;
973 else
974 level = GC_USED;
975 t->u.param_struct.stru->gc_used = GC_UNUSED;
976 set_gc_used_type (t->u.param_struct.stru, level,
977 t->u.param_struct.param);
978 break;
980 default:
981 break;
985 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
987 static void
988 set_gc_used (variables)
989 pair_p variables;
991 pair_p p;
992 for (p = variables; p; p = p->next)
993 set_gc_used_type (p->type, GC_USED, NULL);
996 /* File mapping routines. For each input file, there is one output .c file
997 (but some output files have many input files), and there is one .h file
998 for the whole build. */
1000 /* The list of output files. */
1001 static outf_p output_files;
1003 /* The output header file that is included into pretty much every
1004 source file. */
1005 outf_p header_file;
1007 /* Number of files specified in gtfiles. */
1008 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1010 /* Number of files in the language files array. */
1011 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1013 /* Length of srcdir name. */
1014 static int srcdir_len = 0;
1016 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1017 outf_p base_files[NUM_BASE_FILES];
1019 static outf_p create_file PARAMS ((const char *, const char *));
1020 static const char * get_file_basename PARAMS ((const char *));
1022 /* Create and return an outf_p for a new file for NAME, to be called
1023 ONAME. */
1025 static outf_p
1026 create_file (name, oname)
1027 const char *name;
1028 const char *oname;
1030 static const char *const hdr[] = {
1031 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
1032 "\n",
1033 "This file is part of GCC.\n",
1034 "\n",
1035 "GCC is free software; you can redistribute it and/or modify it under\n",
1036 "the terms of the GNU General Public License as published by the Free\n",
1037 "Software Foundation; either version 2, or (at your option) any later\n",
1038 "version.\n",
1039 "\n",
1040 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1041 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1042 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1043 "for more details.\n",
1044 "\n",
1045 "You should have received a copy of the GNU General Public License\n",
1046 "along with GCC; see the file COPYING. If not, write to the Free\n",
1047 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
1048 "02111-1307, USA. */\n",
1049 "\n",
1050 "/* This file is machine generated. Do not edit. */\n"
1052 outf_p f;
1053 size_t i;
1055 f = xcalloc (sizeof (*f), 1);
1056 f->next = output_files;
1057 f->name = oname;
1058 output_files = f;
1060 oprintf (f, "/* Type information for %s.\n", name);
1061 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1062 oprintf (f, "%s", hdr[i]);
1063 return f;
1066 /* Print, like fprintf, to O. */
1067 void
1068 oprintf VPARAMS ((outf_p o, const char *format, ...))
1070 char *s;
1071 size_t slength;
1073 VA_OPEN (ap, format);
1074 VA_FIXEDARG (ap, outf_p, o);
1075 VA_FIXEDARG (ap, const char *, format);
1076 slength = xvasprintf (&s, format, ap);
1078 if (o->bufused + slength > o->buflength)
1080 size_t new_len = o->buflength;
1081 if (new_len == 0)
1082 new_len = 1024;
1083 do {
1084 new_len *= 2;
1085 } while (o->bufused + slength >= new_len);
1086 o->buf = xrealloc (o->buf, new_len);
1087 o->buflength = new_len;
1089 memcpy (o->buf + o->bufused, s, slength);
1090 o->bufused += slength;
1091 free (s);
1092 VA_CLOSE (ap);
1095 /* Open the global header file and the language-specific header files. */
1097 static void
1098 open_base_files ()
1100 size_t i;
1102 header_file = create_file ("GCC", "gtype-desc.h");
1104 for (i = 0; i < NUM_BASE_FILES; i++)
1105 base_files[i] = create_file (lang_dir_names[i],
1106 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1108 /* gtype-desc.c is a little special, so we create it here. */
1110 /* The order of files here matters very much. */
1111 static const char *const ifiles [] = {
1112 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1113 "hashtab.h", "splay-tree.h", "bitmap.h", "tree.h", "rtl.h",
1114 "function.h", "insn-config.h", "expr.h", "hard-reg-set.h",
1115 "basic-block.h", "cselib.h", "insn-addr.h", "ssa.h", "optabs.h",
1116 "libfuncs.h", "debug.h", "ggc.h",
1117 NULL
1119 const char *const *ifp;
1120 outf_p gtype_desc_c;
1122 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1123 for (ifp = ifiles; *ifp; ifp++)
1124 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1128 /* Determine the pathname to F relative to $(srcdir). */
1130 static const char *
1131 get_file_basename (f)
1132 const char *f;
1134 const char *basename;
1135 unsigned i;
1137 basename = strrchr (f, '/');
1139 if (!basename)
1140 return f;
1142 basename++;
1144 for (i = 1; i < NUM_BASE_FILES; i++)
1146 const char * s1;
1147 const char * s2;
1148 int l1;
1149 int l2;
1150 s1 = basename - strlen (lang_dir_names [i]) - 1;
1151 s2 = lang_dir_names [i];
1152 l1 = strlen (s1);
1153 l2 = strlen (s2);
1154 if (l1 >= l2 && !memcmp (s1, s2, l2))
1156 basename -= l2 + 1;
1157 if ((basename - f - 1) != srcdir_len)
1158 abort (); /* Match is wrong - should be preceded by $srcdir. */
1159 break;
1163 return basename;
1166 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1167 INPUT_FILE is used by <lang>.
1169 This function should be written to assume that a file _is_ used
1170 if the situation is unclear. If it wrongly assumes a file _is_ used,
1171 a linker error will result. If it wrongly assumes a file _is not_ used,
1172 some GC roots may be missed, which is a much harder-to-debug problem. */
1174 unsigned
1175 get_base_file_bitmap (input_file)
1176 const char *input_file;
1178 const char *basename = get_file_basename (input_file);
1179 const char *slashpos = strchr (basename, '/');
1180 unsigned j;
1181 unsigned k;
1182 unsigned bitmap;
1184 if (slashpos)
1186 size_t i;
1187 for (i = 1; i < NUM_BASE_FILES; i++)
1188 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1189 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1191 /* It's in a language directory, set that language. */
1192 bitmap = 1 << i;
1193 return bitmap;
1196 abort (); /* Should have found the language. */
1199 /* If it's in any config-lang.in, then set for the languages
1200 specified. */
1202 bitmap = 0;
1204 for (j = 0; j < NUM_LANG_FILES; j++)
1206 if (!strcmp(input_file, lang_files[j]))
1208 for (k = 0; k < NUM_BASE_FILES; k++)
1210 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1211 bitmap |= (1 << k);
1216 /* Otherwise, set all languages. */
1217 if (!bitmap)
1218 bitmap = (1 << NUM_BASE_FILES) - 1;
1220 return bitmap;
1223 /* An output file, suitable for definitions, that can see declarations
1224 made in INPUT_FILE and is linked into every language that uses
1225 INPUT_FILE. */
1227 outf_p
1228 get_output_file_with_visibility (input_file)
1229 const char *input_file;
1231 outf_p r;
1232 size_t len;
1233 const char *basename;
1234 const char *for_name;
1235 const char *output_name;
1237 /* This can happen when we need a file with visibility on a
1238 structure that we've never seen. We have to just hope that it's
1239 globally visible. */
1240 if (input_file == NULL)
1241 input_file = "system.h";
1243 /* Determine the output file name. */
1244 basename = get_file_basename (input_file);
1246 len = strlen (basename);
1247 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1248 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1249 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1251 char *s;
1253 output_name = s = xasprintf ("gt-%s", basename);
1254 for (; *s != '.'; s++)
1255 if (! ISALNUM (*s) && *s != '-')
1256 *s = '-';
1257 memcpy (s, ".h", sizeof (".h"));
1258 for_name = basename;
1260 else if (strcmp (basename, "c-common.h") == 0)
1261 output_name = "gt-c-common.h", for_name = "c-common.c";
1262 else if (strcmp (basename, "c-tree.h") == 0)
1263 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1264 else
1266 size_t i;
1268 for (i = 0; i < NUM_BASE_FILES; i++)
1269 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1270 && basename[strlen(lang_dir_names[i])] == '/')
1271 return base_files[i];
1273 output_name = "gtype-desc.c";
1274 for_name = NULL;
1277 /* Look through to see if we've ever seen this output filename before. */
1278 for (r = output_files; r; r = r->next)
1279 if (strcmp (r->name, output_name) == 0)
1280 return r;
1282 /* If not, create it. */
1283 r = create_file (for_name, output_name);
1285 return r;
1288 /* The name of an output file, suitable for definitions, that can see
1289 declarations made in INPUT_FILE and is linked into every language
1290 that uses INPUT_FILE. */
1292 const char *
1293 get_output_file_name (input_file)
1294 const char *input_file;
1296 return get_output_file_with_visibility (input_file)->name;
1299 /* Copy the output to its final destination,
1300 but don't unnecessarily change modification times. */
1302 static void close_output_files PARAMS ((void));
1304 static void
1305 close_output_files ()
1307 outf_p of;
1309 for (of = output_files; of; of = of->next)
1311 FILE * newfile;
1313 newfile = fopen (of->name, "r");
1314 if (newfile != NULL )
1316 int no_write_p;
1317 size_t i;
1319 for (i = 0; i < of->bufused; i++)
1321 int ch;
1322 ch = fgetc (newfile);
1323 if (ch == EOF || ch != (unsigned char) of->buf[i])
1324 break;
1326 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1327 fclose (newfile);
1329 if (no_write_p)
1330 continue;
1333 newfile = fopen (of->name, "w");
1334 if (newfile == NULL)
1336 perror ("opening output file");
1337 exit (1);
1339 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1341 perror ("writing output file");
1342 exit (1);
1344 if (fclose (newfile) != 0)
1346 perror ("closing output file");
1347 exit (1);
1352 struct flist {
1353 struct flist *next;
1354 int started_p;
1355 const char *name;
1356 outf_p f;
1359 struct walk_type_data;
1361 /* For scalars and strings, given the item in 'val'.
1362 For structures, given a pointer to the item in 'val'.
1363 For misc. pointers, given the item in 'val'.
1365 typedef void (*process_field_fn)
1366 PARAMS ((type_p f, const struct walk_type_data *p));
1367 typedef void (*func_name_fn)
1368 PARAMS ((type_p s, const struct walk_type_data *p));
1370 /* Parameters for write_types. */
1372 struct write_types_data
1374 const char *prefix;
1375 const char *param_prefix;
1376 const char *subfield_marker_routine;
1377 const char *marker_routine;
1378 const char *reorder_note_routine;
1379 const char *comment;
1382 static void output_escaped_param PARAMS ((struct walk_type_data *d,
1383 const char *, const char *));
1384 static void output_mangled_typename PARAMS ((outf_p, type_p));
1385 static void walk_type PARAMS ((type_p t, struct walk_type_data *d));
1386 static void write_func_for_structure
1387 PARAMS ((type_p orig_s, type_p s, type_p * param,
1388 const struct write_types_data *wtd));
1389 static void write_types_process_field
1390 PARAMS ((type_p f, const struct walk_type_data *d));
1391 static void write_types PARAMS ((type_p structures,
1392 type_p param_structs,
1393 const struct write_types_data *wtd));
1394 static void write_types_local_process_field
1395 PARAMS ((type_p f, const struct walk_type_data *d));
1396 static void write_local_func_for_structure
1397 PARAMS ((type_p orig_s, type_p s, type_p * param));
1398 static void write_local PARAMS ((type_p structures,
1399 type_p param_structs));
1400 static void write_enum_defn PARAMS ((type_p structures, type_p param_structs));
1401 static int contains_scalar_p PARAMS ((type_p t));
1402 static void put_mangled_filename PARAMS ((outf_p , const char *));
1403 static void finish_root_table PARAMS ((struct flist *flp, const char *pfx,
1404 const char *tname, const char *lastname,
1405 const char *name));
1406 static void write_root PARAMS ((outf_p , pair_p, type_p, const char *, int,
1407 struct fileloc *, const char *));
1408 static void write_array PARAMS ((outf_p f, pair_p v,
1409 const struct write_types_data *wtd));
1410 static void write_roots PARAMS ((pair_p));
1412 /* Parameters for walk_type. */
1414 struct walk_type_data
1416 process_field_fn process_field;
1417 const void *cookie;
1418 outf_p of;
1419 options_p opt;
1420 const char *val;
1421 const char *prev_val[4];
1422 int indent;
1423 int counter;
1424 struct fileloc *line;
1425 lang_bitmap bitmap;
1426 type_p *param;
1427 int used_length;
1428 type_p orig_s;
1429 const char *reorder_fn;
1432 /* Print a mangled name representing T to OF. */
1434 static void
1435 output_mangled_typename (of, t)
1436 outf_p of;
1437 type_p t;
1439 if (t == NULL)
1440 oprintf (of, "Z");
1441 else switch (t->kind)
1443 case TYPE_POINTER:
1444 oprintf (of, "P");
1445 output_mangled_typename (of, t->u.p);
1446 break;
1447 case TYPE_SCALAR:
1448 oprintf (of, "I");
1449 break;
1450 case TYPE_STRING:
1451 oprintf (of, "S");
1452 break;
1453 case TYPE_STRUCT:
1454 case TYPE_UNION:
1455 case TYPE_LANG_STRUCT:
1456 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1457 break;
1458 case TYPE_PARAM_STRUCT:
1460 int i;
1461 for (i = 0; i < NUM_PARAM; i++)
1462 if (t->u.param_struct.param[i] != NULL)
1463 output_mangled_typename (of, t->u.param_struct.param[i]);
1464 output_mangled_typename (of, t->u.param_struct.stru);
1466 break;
1467 case TYPE_ARRAY:
1468 abort ();
1472 /* Print PARAM to D->OF processing escapes. D->VAL references the
1473 current object, D->PREV_VAL the object containing the current
1474 object, ONAME is the name of the option and D->LINE is used to
1475 print error messages. */
1477 static void
1478 output_escaped_param (d, param, oname)
1479 struct walk_type_data *d;
1480 const char *param;
1481 const char *oname;
1483 const char *p;
1485 for (p = param; *p; p++)
1486 if (*p != '%')
1487 oprintf (d->of, "%c", *p);
1488 else switch (*++p)
1490 case 'h':
1491 oprintf (d->of, "(%s)", d->prev_val[2]);
1492 break;
1493 case '0':
1494 oprintf (d->of, "(%s)", d->prev_val[0]);
1495 break;
1496 case '1':
1497 oprintf (d->of, "(%s)", d->prev_val[1]);
1498 break;
1499 case 'a':
1501 const char *pp = d->val + strlen (d->val);
1502 while (pp[-1] == ']')
1503 while (*pp != '[')
1504 pp--;
1505 oprintf (d->of, "%s", pp);
1507 break;
1508 default:
1509 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1510 oname, '%', *p);
1514 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1515 which is of type T. Write code to D->OF to constrain execution (at
1516 the point that D->PROCESS_FIELD is called) to the appropriate
1517 cases. D->PREV_VAL lists the objects containing the current object,
1518 D->OPT is a list of options to apply, D->INDENT is the current
1519 indentation level, D->LINE is used to print error messages,
1520 D->BITMAP indicates which languages to print the structure for, and
1521 D->PARAM is the current parameter (from an enclosing param_is
1522 option). */
1524 static void
1525 walk_type (t, d)
1526 type_p t;
1527 struct walk_type_data *d;
1529 const char *length = NULL;
1530 const char *desc = NULL;
1531 int maybe_undef_p = 0;
1532 int use_param_num = -1;
1533 int use_params_p = 0;
1534 int needs_cast_p = 0;
1535 options_p oo;
1537 for (oo = d->opt; oo; oo = oo->next)
1538 if (strcmp (oo->name, "length") == 0)
1539 length = (const char *)oo->info;
1540 else if (strcmp (oo->name, "maybe_undef") == 0)
1541 maybe_undef_p = 1;
1542 else if (strncmp (oo->name, "use_param", 9) == 0
1543 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1544 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1545 else if (strcmp (oo->name, "use_params") == 0)
1546 use_params_p = 1;
1547 else if (strcmp (oo->name, "desc") == 0)
1548 desc = (const char *)oo->info;
1549 else if (strcmp (oo->name, "dot") == 0)
1551 else if (strcmp (oo->name, "tag") == 0)
1553 else if (strcmp (oo->name, "special") == 0)
1555 else if (strcmp (oo->name, "skip") == 0)
1557 else if (strcmp (oo->name, "default") == 0)
1559 else if (strcmp (oo->name, "descbits") == 0)
1561 else if (strcmp (oo->name, "param_is") == 0)
1563 else if (strncmp (oo->name, "param", 5) == 0
1564 && ISDIGIT (oo->name[5])
1565 && strcmp (oo->name + 6, "_is") == 0)
1567 else if (strcmp (oo->name, "chain_next") == 0)
1569 else if (strcmp (oo->name, "chain_prev") == 0)
1571 else if (strcmp (oo->name, "reorder") == 0)
1573 else
1574 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1576 if (d->used_length)
1577 length = NULL;
1579 if (use_params_p)
1581 int pointer_p = t->kind == TYPE_POINTER;
1583 if (pointer_p)
1584 t = t->u.p;
1585 if (! UNION_OR_STRUCT_P (t))
1586 error_at_line (d->line, "`use_params' option on unimplemented type");
1587 else
1588 t = find_param_structure (t, d->param);
1589 if (pointer_p)
1590 t = create_pointer (t);
1593 if (use_param_num != -1)
1595 if (d->param != NULL && d->param[use_param_num] != NULL)
1597 type_p nt = d->param[use_param_num];
1599 if (t->kind == TYPE_ARRAY)
1600 nt = create_array (nt, t->u.a.len);
1601 else if (length != NULL && t->kind == TYPE_POINTER)
1602 nt = create_pointer (nt);
1603 needs_cast_p = (t->kind != TYPE_POINTER
1604 && nt->kind == TYPE_POINTER);
1605 t = nt;
1607 else
1608 error_at_line (d->line, "no parameter defined for `%s'",
1609 d->val);
1612 if (maybe_undef_p
1613 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1615 error_at_line (d->line,
1616 "field `%s' has invalid option `maybe_undef_p'\n",
1617 d->val);
1618 return;
1621 switch (t->kind)
1623 case TYPE_SCALAR:
1624 case TYPE_STRING:
1625 d->process_field (t, d);
1626 break;
1628 case TYPE_POINTER:
1630 if (maybe_undef_p
1631 && t->u.p->u.s.line.file == NULL)
1633 oprintf (d->of, "%*sif (%s) abort();\n", d->indent, "", d->val);
1634 break;
1637 if (! length)
1639 if (! UNION_OR_STRUCT_P (t->u.p)
1640 && t->u.p->kind != TYPE_PARAM_STRUCT)
1642 error_at_line (d->line,
1643 "field `%s' is pointer to unimplemented type",
1644 d->val);
1645 break;
1648 d->process_field (t->u.p, d);
1650 else
1652 int loopcounter = d->counter++;
1653 const char *oldval = d->val;
1654 const char *oldprevval3 = d->prev_val[3];
1655 char *newval;
1657 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1658 d->indent += 2;
1659 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1660 d->process_field(t, d);
1661 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1662 loopcounter, loopcounter);
1663 output_escaped_param (d, length, "length");
1664 oprintf (d->of, "); i%d++) {\n", loopcounter);
1665 d->indent += 2;
1666 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1667 d->used_length = 1;
1668 d->prev_val[3] = oldval;
1669 walk_type (t->u.p, d);
1670 free (newval);
1671 d->val = oldval;
1672 d->prev_val[3] = oldprevval3;
1673 d->used_length = 0;
1674 d->indent -= 2;
1675 oprintf (d->of, "%*s}\n", d->indent, "");
1676 d->indent -= 2;
1677 oprintf (d->of, "%*s}\n", d->indent, "");
1680 break;
1682 case TYPE_ARRAY:
1684 int loopcounter = d->counter++;
1685 const char *oldval = d->val;
1686 char *newval;
1688 /* If it's an array of scalars, we optimise by not generating
1689 any code. */
1690 if (t->u.a.p->kind == TYPE_SCALAR)
1691 break;
1693 oprintf (d->of, "%*s{\n", d->indent, "");
1694 d->indent += 2;
1695 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1696 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1697 loopcounter, loopcounter);
1698 if (length)
1699 output_escaped_param (d, length, "length");
1700 else
1701 oprintf (d->of, "%s", t->u.a.len);
1702 oprintf (d->of, "); i%d++) {\n", loopcounter);
1703 d->indent += 2;
1704 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1705 d->used_length = 1;
1706 walk_type (t->u.a.p, d);
1707 free (newval);
1708 d->used_length = 0;
1709 d->val = oldval;
1710 d->indent -= 2;
1711 oprintf (d->of, "%*s}\n", d->indent, "");
1712 d->indent -= 2;
1713 oprintf (d->of, "%*s}\n", d->indent, "");
1715 break;
1717 case TYPE_STRUCT:
1718 case TYPE_UNION:
1720 pair_p f;
1721 const char *oldval = d->val;
1722 const char *oldprevval1 = d->prev_val[1];
1723 const char *oldprevval2 = d->prev_val[2];
1724 const int union_p = t->kind == TYPE_UNION;
1725 int seen_default_p = 0;
1726 options_p o;
1728 if (! t->u.s.line.file)
1729 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1731 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1733 error_at_line (d->line,
1734 "structure `%s' defined for mismatching languages",
1735 t->u.s.tag);
1736 error_at_line (&t->u.s.line, "one structure defined here");
1739 /* Some things may also be defined in the structure's options. */
1740 for (o = t->u.s.opt; o; o = o->next)
1741 if (! desc && strcmp (o->name, "desc") == 0)
1742 desc = (const char *)o->info;
1744 d->prev_val[2] = oldval;
1745 d->prev_val[1] = oldprevval2;
1746 if (union_p)
1748 if (desc == NULL)
1750 error_at_line (d->line, "missing `desc' option for union `%s'",
1751 t->u.s.tag);
1752 desc = "1";
1754 oprintf (d->of, "%*sswitch (", d->indent, "");
1755 output_escaped_param (d, desc, "desc");
1756 oprintf (d->of, ")\n");
1757 d->indent += 2;
1758 oprintf (d->of, "%*s{\n", d->indent, "");
1760 for (f = t->u.s.fields; f; f = f->next)
1762 options_p oo;
1763 const char *dot = ".";
1764 const char *tagid = NULL;
1765 int skip_p = 0;
1766 int default_p = 0;
1767 int use_param_p = 0;
1768 char *newval;
1770 d->reorder_fn = NULL;
1771 for (oo = f->opt; oo; oo = oo->next)
1772 if (strcmp (oo->name, "dot") == 0)
1773 dot = (const char *)oo->info;
1774 else if (strcmp (oo->name, "tag") == 0)
1775 tagid = (const char *)oo->info;
1776 else if (strcmp (oo->name, "skip") == 0)
1777 skip_p = 1;
1778 else if (strcmp (oo->name, "default") == 0)
1779 default_p = 1;
1780 else if (strcmp (oo->name, "reorder") == 0)
1781 d->reorder_fn = (const char *)oo->info;
1782 else if (strncmp (oo->name, "use_param", 9) == 0
1783 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1784 use_param_p = 1;
1786 if (skip_p)
1787 continue;
1789 if (union_p && tagid)
1791 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1792 d->indent += 2;
1794 else if (union_p && default_p)
1796 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1797 d->indent += 2;
1798 seen_default_p = 1;
1800 else if (! union_p && (default_p || tagid))
1801 error_at_line (d->line,
1802 "can't use `%s' outside a union on field `%s'",
1803 default_p ? "default" : "tag", f->name);
1804 else if (union_p && ! (default_p || tagid)
1805 && f->type->kind == TYPE_SCALAR)
1807 fprintf (stderr,
1808 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1809 d->line->file, d->line->line, f->name);
1810 continue;
1812 else if (union_p && ! (default_p || tagid))
1813 error_at_line (d->line,
1814 "field `%s' is missing `tag' or `default' option",
1815 f->name);
1817 d->line = &f->line;
1818 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1819 d->opt = f->opt;
1821 if (union_p && use_param_p && d->param == NULL)
1822 oprintf (d->of, "%*sabort();\n", d->indent, "");
1823 else
1824 walk_type (f->type, d);
1826 free (newval);
1828 if (union_p)
1830 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1831 d->indent -= 2;
1834 d->reorder_fn = NULL;
1836 d->val = oldval;
1837 d->prev_val[1] = oldprevval1;
1838 d->prev_val[2] = oldprevval2;
1840 if (union_p && ! seen_default_p)
1842 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1843 oprintf (d->of, "%*s break;\n", d->indent, "");
1845 if (union_p)
1847 oprintf (d->of, "%*s}\n", d->indent, "");
1848 d->indent -= 2;
1851 break;
1853 case TYPE_LANG_STRUCT:
1855 type_p nt;
1856 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1857 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1858 break;
1859 if (nt == NULL)
1860 error_at_line (d->line, "structure `%s' differs between languages",
1861 t->u.s.tag);
1862 else
1863 walk_type (nt, d);
1865 break;
1867 case TYPE_PARAM_STRUCT:
1869 type_p *oldparam = d->param;
1871 d->param = t->u.param_struct.param;
1872 walk_type (t->u.param_struct.stru, d);
1873 d->param = oldparam;
1875 break;
1877 default:
1878 abort ();
1882 /* process_field routine for marking routines. */
1884 static void
1885 write_types_process_field (f, d)
1886 type_p f;
1887 const struct walk_type_data *d;
1889 const struct write_types_data *wtd;
1890 wtd = (const struct write_types_data *) d->cookie;
1892 switch (f->kind)
1894 case TYPE_POINTER:
1895 oprintf (d->of, "%*s%s (%s", d->indent, "",
1896 wtd->subfield_marker_routine, d->val);
1897 if (wtd->param_prefix)
1899 oprintf (d->of, ", %s", d->prev_val[3]);
1900 if (d->orig_s)
1902 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1903 output_mangled_typename (d->of, d->orig_s);
1905 else
1906 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1908 oprintf (d->of, ");\n");
1909 if (d->reorder_fn && wtd->reorder_note_routine)
1910 oprintf (d->of, "%*s%s (%s, %s, %s);\n", d->indent, "",
1911 wtd->reorder_note_routine, d->val,
1912 d->prev_val[3], d->reorder_fn);
1913 break;
1915 case TYPE_STRING:
1916 if (wtd->param_prefix == NULL)
1917 break;
1919 case TYPE_STRUCT:
1920 case TYPE_UNION:
1921 case TYPE_LANG_STRUCT:
1922 case TYPE_PARAM_STRUCT:
1923 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1924 output_mangled_typename (d->of, f);
1925 oprintf (d->of, " (%s);\n", d->val);
1926 if (d->reorder_fn && wtd->reorder_note_routine)
1927 oprintf (d->of, "%*s%s (%s, %s, %s);\n", d->indent, "",
1928 wtd->reorder_note_routine, d->val, d->val,
1929 d->reorder_fn);
1930 break;
1932 case TYPE_SCALAR:
1933 break;
1935 default:
1936 abort ();
1940 /* For S, a structure that's part of ORIG_S, and using parameters
1941 PARAM, write out a routine that:
1942 - Takes a parameter, a void * but actually of type *S
1943 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1944 field of S or its substructures and (in some cases) things
1945 that are pointed to by S.
1948 static void
1949 write_func_for_structure (orig_s, s, param, wtd)
1950 type_p orig_s;
1951 type_p s;
1952 type_p * param;
1953 const struct write_types_data *wtd;
1955 const char *fn = s->u.s.line.file;
1956 int i;
1957 const char *chain_next = NULL;
1958 const char *chain_prev = NULL;
1959 options_p opt;
1960 struct walk_type_data d;
1962 /* This is a hack, and not the good kind either. */
1963 for (i = NUM_PARAM - 1; i >= 0; i--)
1964 if (param && param[i] && param[i]->kind == TYPE_POINTER
1965 && UNION_OR_STRUCT_P (param[i]->u.p))
1966 fn = param[i]->u.p->u.s.line.file;
1968 memset (&d, 0, sizeof (d));
1969 d.of = get_output_file_with_visibility (fn);
1971 for (opt = s->u.s.opt; opt; opt = opt->next)
1972 if (strcmp (opt->name, "chain_next") == 0)
1973 chain_next = (const char *) opt->info;
1974 else if (strcmp (opt->name, "chain_prev") == 0)
1975 chain_prev = (const char *) opt->info;
1977 if (chain_prev != NULL && chain_next == NULL)
1978 error_at_line (&s->u.s.line, "chain_prev without chain_next");
1980 d.process_field = write_types_process_field;
1981 d.cookie = wtd;
1982 d.orig_s = orig_s;
1983 d.opt = s->u.s.opt;
1984 d.line = &s->u.s.line;
1985 d.bitmap = s->u.s.bitmap;
1986 d.param = param;
1987 d.prev_val[0] = "*x";
1988 d.prev_val[1] = "not valid postage"; /* guarantee an error */
1989 d.prev_val[3] = "x";
1990 d.val = "(*x)";
1992 oprintf (d.of, "\n");
1993 oprintf (d.of, "void\n");
1994 if (param == NULL)
1995 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
1996 else
1998 oprintf (d.of, "gt_%s_", wtd->prefix);
1999 output_mangled_typename (d.of, orig_s);
2001 oprintf (d.of, " (x_p)\n");
2002 oprintf (d.of, " void *x_p;\n");
2003 oprintf (d.of, "{\n");
2004 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2005 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2006 chain_next == NULL ? "const " : "",
2007 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2008 if (chain_next != NULL)
2009 oprintf (d.of, " %s %s * xlimit = x;\n",
2010 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2011 if (chain_next == NULL)
2013 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2014 if (wtd->param_prefix)
2016 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2017 output_mangled_typename (d.of, orig_s);
2019 oprintf (d.of, "))\n");
2021 else
2023 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2024 if (wtd->param_prefix)
2026 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2027 output_mangled_typename (d.of, orig_s);
2029 oprintf (d.of, "))\n");
2030 oprintf (d.of, " xlimit = (");
2031 d.prev_val[2] = "*xlimit";
2032 output_escaped_param (&d, chain_next, "chain_next");
2033 oprintf (d.of, ");\n");
2034 if (chain_prev != NULL)
2036 oprintf (d.of, " if (x != xlimit)\n");
2037 oprintf (d.of, " for (;;)\n");
2038 oprintf (d.of, " {\n");
2039 oprintf (d.of, " %s %s * const xprev = (",
2040 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2042 d.prev_val[2] = "*x";
2043 output_escaped_param (&d, chain_prev, "chain_prev");
2044 oprintf (d.of, ");\n");
2045 oprintf (d.of, " if (xprev == NULL) break;\n");
2046 oprintf (d.of, " x = xprev;\n");
2047 oprintf (d.of, " (void) %s (xprev",
2048 wtd->marker_routine);
2049 if (wtd->param_prefix)
2051 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2052 output_mangled_typename (d.of, orig_s);
2054 oprintf (d.of, ");\n");
2055 oprintf (d.of, " }\n");
2057 oprintf (d.of, " while (x != xlimit)\n");
2059 oprintf (d.of, " {\n");
2061 d.prev_val[2] = "*x";
2062 d.indent = 6;
2063 walk_type (s, &d);
2065 if (chain_next != NULL)
2067 oprintf (d.of, " x = (");
2068 output_escaped_param (&d, chain_next, "chain_next");
2069 oprintf (d.of, ");\n");
2072 oprintf (d.of, " }\n");
2073 oprintf (d.of, "}\n");
2076 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2078 static void
2079 write_types (structures, param_structs, wtd)
2080 type_p structures;
2081 type_p param_structs;
2082 const struct write_types_data *wtd;
2084 type_p s;
2086 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2087 for (s = structures; s; s = s->next)
2088 if (s->gc_used == GC_POINTED_TO
2089 || s->gc_used == GC_MAYBE_POINTED_TO)
2091 options_p opt;
2093 if (s->gc_used == GC_MAYBE_POINTED_TO
2094 && s->u.s.line.file == NULL)
2095 continue;
2097 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2098 output_mangled_typename (header_file, s);
2099 oprintf (header_file, "(X) do { \\\n");
2100 oprintf (header_file,
2101 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2102 s->u.s.tag);
2103 oprintf (header_file,
2104 " } while (0)\n");
2106 for (opt = s->u.s.opt; opt; opt = opt->next)
2107 if (strcmp (opt->name, "ptr_alias") == 0)
2109 type_p t = (type_p) opt->info;
2110 if (t->kind == TYPE_STRUCT
2111 || t->kind == TYPE_UNION
2112 || t->kind == TYPE_LANG_STRUCT)
2113 oprintf (header_file,
2114 "#define gt_%sx_%s gt_%sx_%s\n",
2115 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2116 else
2117 error_at_line (&s->u.s.line,
2118 "structure alias is not a structure");
2119 break;
2121 if (opt)
2122 continue;
2124 /* Declare the marker procedure only once. */
2125 oprintf (header_file,
2126 "extern void gt_%sx_%s PARAMS ((void *));\n",
2127 wtd->prefix, s->u.s.tag);
2129 if (s->u.s.line.file == NULL)
2131 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2132 s->u.s.tag);
2133 continue;
2136 if (s->kind == TYPE_LANG_STRUCT)
2138 type_p ss;
2139 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2140 write_func_for_structure (s, ss, NULL, wtd);
2142 else
2143 write_func_for_structure (s, s, NULL, wtd);
2146 for (s = param_structs; s; s = s->next)
2147 if (s->gc_used == GC_POINTED_TO)
2149 type_p * param = s->u.param_struct.param;
2150 type_p stru = s->u.param_struct.stru;
2152 /* Declare the marker procedure. */
2153 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2154 output_mangled_typename (header_file, s);
2155 oprintf (header_file, " PARAMS ((void *));\n");
2157 if (stru->u.s.line.file == NULL)
2159 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2160 s->u.s.tag);
2161 continue;
2164 if (stru->kind == TYPE_LANG_STRUCT)
2166 type_p ss;
2167 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2168 write_func_for_structure (s, ss, param, wtd);
2170 else
2171 write_func_for_structure (s, stru, param, wtd);
2175 static const struct write_types_data ggc_wtd =
2177 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2178 "GC marker procedures. "
2181 static const struct write_types_data pch_wtd =
2183 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2184 "gt_pch_note_reorder",
2185 "PCH type-walking procedures. "
2188 /* Write out the local pointer-walking routines. */
2190 /* process_field routine for local pointer-walking. */
2192 static void
2193 write_types_local_process_field (f, d)
2194 type_p f;
2195 const struct walk_type_data *d;
2197 switch (f->kind)
2199 case TYPE_POINTER:
2200 case TYPE_STRUCT:
2201 case TYPE_UNION:
2202 case TYPE_LANG_STRUCT:
2203 case TYPE_PARAM_STRUCT:
2204 case TYPE_STRING:
2205 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2206 d->prev_val[3]);
2207 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2208 break;
2210 case TYPE_SCALAR:
2211 break;
2213 default:
2214 abort ();
2218 /* For S, a structure that's part of ORIG_S, and using parameters
2219 PARAM, write out a routine that:
2220 - Is of type gt_note_pointers
2221 - If calls PROCESS_FIELD on each field of S or its substructures.
2224 static void
2225 write_local_func_for_structure (orig_s, s, param)
2226 type_p orig_s;
2227 type_p s;
2228 type_p * param;
2230 const char *fn = s->u.s.line.file;
2231 int i;
2232 struct walk_type_data d;
2234 /* This is a hack, and not the good kind either. */
2235 for (i = NUM_PARAM - 1; i >= 0; i--)
2236 if (param && param[i] && param[i]->kind == TYPE_POINTER
2237 && UNION_OR_STRUCT_P (param[i]->u.p))
2238 fn = param[i]->u.p->u.s.line.file;
2240 memset (&d, 0, sizeof (d));
2241 d.of = get_output_file_with_visibility (fn);
2243 d.process_field = write_types_local_process_field;
2244 d.opt = s->u.s.opt;
2245 d.line = &s->u.s.line;
2246 d.bitmap = s->u.s.bitmap;
2247 d.param = param;
2248 d.prev_val[0] = d.prev_val[2] = "*x";
2249 d.prev_val[1] = "not valid postage"; /* guarantee an error */
2250 d.prev_val[3] = "x";
2251 d.val = "(*x)";
2253 oprintf (d.of, "\n");
2254 oprintf (d.of, "void\n");
2255 oprintf (d.of, "gt_pch_p_");
2256 output_mangled_typename (d.of, orig_s);
2257 oprintf (d.of, " (this_obj, x_p, op, cookie)\n");
2258 oprintf (d.of, " void *this_obj ATTRIBUTE_UNUSED;\n");
2259 oprintf (d.of, " void *x_p;\n");
2260 oprintf (d.of, " gt_pointer_operator op ATTRIBUTE_UNUSED;\n");
2261 oprintf (d.of, " void *cookie ATTRIBUTE_UNUSED;\n");
2262 oprintf (d.of, "{\n");
2263 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2264 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2265 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2266 d.indent = 2;
2267 walk_type (s, &d);
2268 oprintf (d.of, "}\n");
2271 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2273 static void
2274 write_local (structures, param_structs)
2275 type_p structures;
2276 type_p param_structs;
2278 type_p s;
2280 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2281 for (s = structures; s; s = s->next)
2282 if (s->gc_used == GC_POINTED_TO
2283 || s->gc_used == GC_MAYBE_POINTED_TO)
2285 options_p opt;
2287 if (s->u.s.line.file == NULL)
2288 continue;
2290 for (opt = s->u.s.opt; opt; opt = opt->next)
2291 if (strcmp (opt->name, "ptr_alias") == 0)
2293 type_p t = (type_p) opt->info;
2294 if (t->kind == TYPE_STRUCT
2295 || t->kind == TYPE_UNION
2296 || t->kind == TYPE_LANG_STRUCT)
2298 oprintf (header_file, "#define gt_pch_p_");
2299 output_mangled_typename (header_file, s);
2300 oprintf (header_file, " gt_pch_p_");
2301 output_mangled_typename (header_file, t);
2302 oprintf (header_file, "\n");
2304 else
2305 error_at_line (&s->u.s.line,
2306 "structure alias is not a structure");
2307 break;
2309 if (opt)
2310 continue;
2312 /* Declare the marker procedure only once. */
2313 oprintf (header_file, "extern void gt_pch_p_");
2314 output_mangled_typename (header_file, s);
2315 oprintf (header_file,
2316 "\n PARAMS ((void *, void *, gt_pointer_operator, void *));\n");
2318 if (s->kind == TYPE_LANG_STRUCT)
2320 type_p ss;
2321 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2322 write_local_func_for_structure (s, ss, NULL);
2324 else
2325 write_local_func_for_structure (s, s, NULL);
2328 for (s = param_structs; s; s = s->next)
2329 if (s->gc_used == GC_POINTED_TO)
2331 type_p * param = s->u.param_struct.param;
2332 type_p stru = s->u.param_struct.stru;
2334 /* Declare the marker procedure. */
2335 oprintf (header_file, "extern void gt_pch_p_");
2336 output_mangled_typename (header_file, s);
2337 oprintf (header_file,
2338 "\n PARAMS ((void *, void *, gt_pointer_operator, void *));\n");
2340 if (stru->u.s.line.file == NULL)
2342 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2343 s->u.s.tag);
2344 continue;
2347 if (stru->kind == TYPE_LANG_STRUCT)
2349 type_p ss;
2350 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2351 write_local_func_for_structure (s, ss, param);
2353 else
2354 write_local_func_for_structure (s, stru, param);
2358 /* Write out the 'enum' definition for gt_types_enum. */
2360 static void
2361 write_enum_defn (structures, param_structs)
2362 type_p structures;
2363 type_p param_structs;
2365 type_p s;
2367 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2368 oprintf (header_file, "enum gt_types_enum {\n");
2369 for (s = structures; s; s = s->next)
2370 if (s->gc_used == GC_POINTED_TO
2371 || s->gc_used == GC_MAYBE_POINTED_TO)
2373 if (s->gc_used == GC_MAYBE_POINTED_TO
2374 && s->u.s.line.file == NULL)
2375 continue;
2377 oprintf (header_file, " gt_ggc_e_");
2378 output_mangled_typename (header_file, s);
2379 oprintf (header_file, ", \n");
2381 for (s = param_structs; s; s = s->next)
2382 if (s->gc_used == GC_POINTED_TO)
2384 oprintf (header_file, " gt_e_");
2385 output_mangled_typename (header_file, s);
2386 oprintf (header_file, ", \n");
2388 oprintf (header_file, " gt_types_enum_last\n");
2389 oprintf (header_file, "};\n");
2392 /* Might T contain any non-pointer elements? */
2394 static int
2395 contains_scalar_p (t)
2396 type_p t;
2398 switch (t->kind)
2400 case TYPE_STRING:
2401 case TYPE_POINTER:
2402 return 0;
2403 case TYPE_ARRAY:
2404 return contains_scalar_p (t->u.a.p);
2405 default:
2406 /* Could also check for structures that have no non-pointer
2407 fields, but there aren't enough of those to worry about. */
2408 return 1;
2412 /* Mangle FN and print it to F. */
2414 static void
2415 put_mangled_filename (f, fn)
2416 outf_p f;
2417 const char *fn;
2419 const char *name = get_output_file_name (fn);
2420 for (; *name != 0; name++)
2421 if (ISALNUM (*name))
2422 oprintf (f, "%c", *name);
2423 else
2424 oprintf (f, "%c", '_');
2427 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2428 LASTNAME, and NAME are all strings to insert in various places in
2429 the resulting code. */
2431 static void
2432 finish_root_table (flp, pfx, lastname, tname, name)
2433 struct flist *flp;
2434 const char *pfx;
2435 const char *tname;
2436 const char *lastname;
2437 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 (f, v, type, name, has_length, line, if_marked)
2508 outf_p f;
2509 pair_p v;
2510 type_p type;
2511 const char *name;
2512 int has_length;
2513 struct fileloc *line;
2514 const char *if_marked;
2516 switch (type->kind)
2518 case TYPE_STRUCT:
2520 pair_p fld;
2521 for (fld = type->u.s.fields; fld; fld = fld->next)
2523 int skip_p = 0;
2524 const char *desc = NULL;
2525 options_p o;
2527 for (o = fld->opt; o; o = o->next)
2528 if (strcmp (o->name, "skip") == 0)
2529 skip_p = 1;
2530 else if (strcmp (o->name, "desc") == 0)
2531 desc = (const char *)o->info;
2532 else
2533 error_at_line (line,
2534 "field `%s' of global `%s' has unknown option `%s'",
2535 fld->name, name, o->name);
2537 if (skip_p)
2538 continue;
2539 else if (desc && fld->type->kind == TYPE_UNION)
2541 pair_p validf = NULL;
2542 pair_p ufld;
2544 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2546 const char *tag = NULL;
2547 options_p oo;
2549 for (oo = ufld->opt; oo; oo = oo->next)
2550 if (strcmp (oo->name, "tag") == 0)
2551 tag = (const char *)oo->info;
2552 if (tag == NULL || strcmp (tag, desc) != 0)
2553 continue;
2554 if (validf != NULL)
2555 error_at_line (line,
2556 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2557 name, fld->name, validf->name,
2558 name, fld->name, ufld->name,
2559 tag);
2560 validf = ufld;
2562 if (validf != NULL)
2564 char *newname;
2565 newname = xasprintf ("%s.%s.%s",
2566 name, fld->name, validf->name);
2567 write_root (f, v, validf->type, newname, 0, line,
2568 if_marked);
2569 free (newname);
2572 else if (desc)
2573 error_at_line (line,
2574 "global `%s.%s' has `desc' option but is not union",
2575 name, fld->name);
2576 else
2578 char *newname;
2579 newname = xasprintf ("%s.%s", name, fld->name);
2580 write_root (f, v, fld->type, newname, 0, line, if_marked);
2581 free (newname);
2585 break;
2587 case TYPE_ARRAY:
2589 char *newname;
2590 newname = xasprintf ("%s[0]", name);
2591 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2592 free (newname);
2594 break;
2596 case TYPE_POINTER:
2598 type_p ap, tp;
2600 oprintf (f, " {\n");
2601 oprintf (f, " &%s,\n", name);
2602 oprintf (f, " 1");
2604 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2605 if (ap->u.a.len[0])
2606 oprintf (f, " * (%s)", ap->u.a.len);
2607 else if (ap == v->type)
2608 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2609 oprintf (f, ",\n");
2610 oprintf (f, " sizeof (%s", v->name);
2611 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2612 oprintf (f, "[0]");
2613 oprintf (f, "),\n");
2615 tp = type->u.p;
2617 if (! has_length && UNION_OR_STRUCT_P (tp))
2619 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2620 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2622 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2624 oprintf (f, " &gt_ggc_m_");
2625 output_mangled_typename (f, tp);
2626 oprintf (f, ",\n &gt_pch_n_");
2627 output_mangled_typename (f, tp);
2629 else if (has_length
2630 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2632 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2633 oprintf (f, " &gt_pch_na_%s", name);
2635 else
2637 error_at_line (line,
2638 "global `%s' is pointer to unimplemented type",
2639 name);
2641 if (if_marked)
2642 oprintf (f, ",\n &%s", if_marked);
2643 oprintf (f, "\n },\n");
2645 break;
2647 case TYPE_STRING:
2649 oprintf (f, " {\n");
2650 oprintf (f, " &%s,\n", name);
2651 oprintf (f, " 1, \n");
2652 oprintf (f, " sizeof (%s),\n", v->name);
2653 oprintf (f, " &gt_ggc_m_S,\n");
2654 oprintf (f, " &gt_pch_n_S\n");
2655 oprintf (f, " },\n");
2657 break;
2659 case TYPE_SCALAR:
2660 break;
2662 default:
2663 error_at_line (line,
2664 "global `%s' is unimplemented type",
2665 name);
2669 /* This generates a routine to walk an array. */
2671 static void
2672 write_array (f, v, wtd)
2673 outf_p f;
2674 pair_p v;
2675 const struct write_types_data *wtd;
2677 struct walk_type_data d;
2678 char *prevval3;
2680 memset (&d, 0, sizeof (d));
2681 d.of = f;
2682 d.cookie = wtd;
2683 d.indent = 2;
2684 d.line = &v->line;
2685 d.opt = v->opt;
2686 d.bitmap = get_base_file_bitmap (v->line.file);
2687 d.param = NULL;
2689 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2691 if (wtd->param_prefix)
2693 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2694 oprintf (f,
2695 " PARAMS ((void *, void *, gt_pointer_operator, void *));\n");
2696 oprintf (f, "static void gt_%sa_%s (this_obj, x_p, op, cookie)\n",
2697 wtd->param_prefix, v->name);
2698 oprintf (d.of, " void *this_obj ATTRIBUTE_UNUSED;\n");
2699 oprintf (d.of, " void *x_p ATTRIBUTE_UNUSED;\n");
2700 oprintf (d.of, " gt_pointer_operator op ATTRIBUTE_UNUSED;\n");
2701 oprintf (d.of, " void *cookie ATTRIBUTE_UNUSED;\n");
2702 oprintf (d.of, "{\n");
2703 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2704 d.process_field = write_types_local_process_field;
2705 walk_type (v->type, &d);
2706 oprintf (f, "}\n\n");
2709 d.opt = v->opt;
2710 oprintf (f, "static void gt_%sa_%s PARAMS ((void *));\n",
2711 wtd->prefix, v->name);
2712 oprintf (f, "static void\ngt_%sa_%s (x_p)\n",
2713 wtd->prefix, v->name);
2714 oprintf (f, " void *x_p ATTRIBUTE_UNUSED;\n");
2715 oprintf (f, "{\n");
2716 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2717 d.process_field = write_types_process_field;
2718 walk_type (v->type, &d);
2719 free (prevval3);
2720 oprintf (f, "}\n\n");
2723 /* Output a table describing the locations and types of VARIABLES. */
2725 static void
2726 write_roots (variables)
2727 pair_p variables;
2729 pair_p v;
2730 struct flist *flp = NULL;
2732 for (v = variables; v; v = v->next)
2734 outf_p f = get_output_file_with_visibility (v->line.file);
2735 struct flist *fli;
2736 const char *length = NULL;
2737 int deletable_p = 0;
2738 options_p o;
2740 for (o = v->opt; o; o = o->next)
2741 if (strcmp (o->name, "length") == 0)
2742 length = (const char *)o->info;
2743 else if (strcmp (o->name, "deletable") == 0)
2744 deletable_p = 1;
2745 else if (strcmp (o->name, "param_is") == 0)
2747 else if (strncmp (o->name, "param", 5) == 0
2748 && ISDIGIT (o->name[5])
2749 && strcmp (o->name + 6, "_is") == 0)
2751 else if (strcmp (o->name, "if_marked") == 0)
2753 else
2754 error_at_line (&v->line,
2755 "global `%s' has unknown option `%s'",
2756 v->name, o->name);
2758 for (fli = flp; fli; fli = fli->next)
2759 if (fli->f == f)
2760 break;
2761 if (fli == NULL)
2763 fli = xmalloc (sizeof (*fli));
2764 fli->f = f;
2765 fli->next = flp;
2766 fli->started_p = 0;
2767 fli->name = v->line.file;
2768 flp = fli;
2770 oprintf (f, "\n/* GC roots. */\n\n");
2773 if (! deletable_p
2774 && length
2775 && v->type->kind == TYPE_POINTER
2776 && (v->type->u.p->kind == TYPE_POINTER
2777 || v->type->u.p->kind == TYPE_STRUCT))
2779 write_array (f, v, &ggc_wtd);
2780 write_array (f, v, &pch_wtd);
2784 for (v = variables; v; v = v->next)
2786 outf_p f = get_output_file_with_visibility (v->line.file);
2787 struct flist *fli;
2788 int skip_p = 0;
2789 int length_p = 0;
2790 options_p o;
2792 for (o = v->opt; o; o = o->next)
2793 if (strcmp (o->name, "length") == 0)
2794 length_p = 1;
2795 else if (strcmp (o->name, "deletable") == 0
2796 || strcmp (o->name, "if_marked") == 0)
2797 skip_p = 1;
2799 if (skip_p)
2800 continue;
2802 for (fli = flp; fli; fli = fli->next)
2803 if (fli->f == f)
2804 break;
2805 if (! fli->started_p)
2807 fli->started_p = 1;
2809 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2810 put_mangled_filename (f, v->line.file);
2811 oprintf (f, "[] = {\n");
2814 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2817 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2818 "gt_ggc_rtab");
2820 for (v = variables; v; v = v->next)
2822 outf_p f = get_output_file_with_visibility (v->line.file);
2823 struct flist *fli;
2824 int skip_p = 1;
2825 options_p o;
2827 for (o = v->opt; o; o = o->next)
2828 if (strcmp (o->name, "deletable") == 0)
2829 skip_p = 0;
2830 else if (strcmp (o->name, "if_marked") == 0)
2831 skip_p = 1;
2833 if (skip_p)
2834 continue;
2836 for (fli = flp; fli; fli = fli->next)
2837 if (fli->f == f)
2838 break;
2839 if (! fli->started_p)
2841 fli->started_p = 1;
2843 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2844 put_mangled_filename (f, v->line.file);
2845 oprintf (f, "[] = {\n");
2848 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2849 v->name, v->name);
2852 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2853 "gt_ggc_deletable_rtab");
2855 for (v = variables; v; v = v->next)
2857 outf_p f = get_output_file_with_visibility (v->line.file);
2858 struct flist *fli;
2859 const char *if_marked = NULL;
2860 int length_p = 0;
2861 options_p o;
2863 for (o = v->opt; o; o = o->next)
2864 if (strcmp (o->name, "length") == 0)
2865 length_p = 1;
2866 else if (strcmp (o->name, "if_marked") == 0)
2867 if_marked = (const char *) o->info;
2869 if (if_marked == NULL)
2870 continue;
2872 if (v->type->kind != TYPE_POINTER
2873 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2874 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2876 error_at_line (&v->line, "if_marked option used but not hash table");
2877 continue;
2880 for (fli = flp; fli; fli = fli->next)
2881 if (fli->f == f)
2882 break;
2883 if (! fli->started_p)
2885 fli->started_p = 1;
2887 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2888 put_mangled_filename (f, v->line.file);
2889 oprintf (f, "[] = {\n");
2892 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2893 v->name, length_p, &v->line, if_marked);
2896 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2897 "gt_ggc_cache_rtab");
2899 for (v = variables; v; v = v->next)
2901 outf_p f = get_output_file_with_visibility (v->line.file);
2902 struct flist *fli;
2903 int length_p = 0;
2904 int if_marked_p = 0;
2905 options_p o;
2907 for (o = v->opt; o; o = o->next)
2908 if (strcmp (o->name, "length") == 0)
2909 length_p = 1;
2910 else if (strcmp (o->name, "if_marked") == 0)
2911 if_marked_p = 1;
2913 if (! if_marked_p)
2914 continue;
2916 for (fli = flp; fli; fli = fli->next)
2917 if (fli->f == f)
2918 break;
2919 if (! fli->started_p)
2921 fli->started_p = 1;
2923 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2924 put_mangled_filename (f, v->line.file);
2925 oprintf (f, "[] = {\n");
2928 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2931 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2932 "gt_pch_cache_rtab");
2934 for (v = variables; v; v = v->next)
2936 outf_p f = get_output_file_with_visibility (v->line.file);
2937 struct flist *fli;
2938 int skip_p = 0;
2939 options_p o;
2941 for (o = v->opt; o; o = o->next)
2942 if (strcmp (o->name, "deletable") == 0
2943 || strcmp (o->name, "if_marked") == 0)
2944 skip_p = 1;
2946 if (skip_p)
2947 continue;
2949 if (! contains_scalar_p (v->type))
2950 continue;
2952 for (fli = flp; fli; fli = fli->next)
2953 if (fli->f == f)
2954 break;
2955 if (! fli->started_p)
2957 fli->started_p = 1;
2959 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2960 put_mangled_filename (f, v->line.file);
2961 oprintf (f, "[] = {\n");
2964 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2965 v->name, v->name);
2968 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2969 "gt_pch_scalar_rtab");
2973 extern int main PARAMS ((int argc, char **argv));
2974 int
2975 main(argc, argv)
2976 int argc ATTRIBUTE_UNUSED;
2977 char **argv ATTRIBUTE_UNUSED;
2979 unsigned i;
2980 static struct fileloc pos = { __FILE__, __LINE__ };
2981 unsigned j;
2983 gen_rtx_next ();
2985 srcdir_len = strlen (srcdir);
2987 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
2988 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
2989 do_scalar_typedef ("uint8", &pos);
2990 do_scalar_typedef ("jword", &pos);
2991 do_scalar_typedef ("JCF_u2", &pos);
2993 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
2994 strlen ("void"))),
2995 &pos);
2996 do_typedef ("HARD_REG_SET", create_array (
2997 create_scalar_type ("unsigned long", strlen ("unsigned long")),
2998 "2"), &pos);
3000 for (i = 0; i < NUM_GT_FILES; i++)
3002 int dupflag = 0;
3003 /* Omit if already seen. */
3004 for (j = 0; j < i; j++)
3006 if (!strcmp (all_files[i], all_files[j]))
3008 dupflag = 1;
3009 break;
3012 if (!dupflag)
3013 parse_file (all_files[i]);
3016 if (hit_error != 0)
3017 exit (1);
3019 set_gc_used (variables);
3021 open_base_files ();
3022 write_enum_defn (structures, param_structs);
3023 write_types (structures, param_structs, &ggc_wtd);
3024 write_types (structures, param_structs, &pch_wtd);
3025 write_local (structures, param_structs);
3026 write_roots (variables);
3027 write_rtx_next ();
3028 close_output_files ();
3030 return (hit_error != 0);