PR libgfortran/27107:
[official-gcc.git] / gcc / gengtype.c
blobf62659ada47a57d1271cf0b7609779319b324be7
1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, 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 and return a new structure with tag NAME (or a union iff
147 ISUNION is nonzero), at POS with fields FIELDS and options O. */
149 type_p
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;
218 return s;
221 /* Return the previously-defined structure with tag NAME (or a union
222 iff ISUNION is nonzero), or a new empty structure or union if none
223 was defined previously. */
225 type_p
226 find_structure (const char *name, int isunion)
228 type_p s;
230 for (s = structures; s != NULL; s = s->next)
231 if (strcmp (name, s->u.s.tag) == 0
232 && UNION_P (s) == isunion)
233 return s;
235 s = XCNEW (struct type);
236 s->next = structures;
237 structures = s;
238 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
239 s->u.s.tag = name;
240 structures = s;
241 return s;
244 /* Return the previously-defined parameterized structure for structure
245 T and parameters PARAM, or a new parameterized empty structure or
246 union if none was defined previously. */
248 static type_p
249 find_param_structure (type_p t, type_p param[NUM_PARAM])
251 type_p res;
253 for (res = param_structs; res; res = res->next)
254 if (res->u.param_struct.stru == t
255 && memcmp (res->u.param_struct.param, param,
256 sizeof (type_p) * NUM_PARAM) == 0)
257 break;
258 if (res == NULL)
260 res = XCNEW (struct type);
261 res->kind = TYPE_PARAM_STRUCT;
262 res->next = param_structs;
263 param_structs = res;
264 res->u.param_struct.stru = t;
265 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
267 return res;
270 /* Return a scalar type with name NAME. */
272 type_p
273 create_scalar_type (const char *name, size_t name_len)
275 type_p r = XCNEW (struct type);
276 r->kind = TYPE_SCALAR;
277 r->u.sc = (char *) xmemdup (name, name_len, name_len + 1);
278 return r;
281 /* Return a pointer to T. */
283 type_p
284 create_pointer (type_p t)
286 if (! t->pointer_to)
288 type_p r = XCNEW (struct type);
289 r->kind = TYPE_POINTER;
290 r->u.p = t;
291 t->pointer_to = r;
293 return t->pointer_to;
296 /* Return an array of length LEN. */
298 type_p
299 create_array (type_p t, const char *len)
301 type_p v;
303 v = XCNEW (struct type);
304 v->kind = TYPE_ARRAY;
305 v->u.a.p = t;
306 v->u.a.len = len;
307 return v;
310 /* Return an options structure with name NAME and info INFO. NEXT is the
311 next option in the chain. */
313 options_p
314 create_option (options_p next, const char *name, const void *info)
316 options_p o = XNEW (struct options);
317 o->next = next;
318 o->name = name;
319 o->info = (const char*) info;
320 return o;
323 /* Add a variable named S of type T with options O defined at POS,
324 to `variables'. */
326 void
327 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
329 pair_p n;
330 n = XNEW (struct pair);
331 n->name = s;
332 n->type = t;
333 n->line = *pos;
334 n->opt = o;
335 n->next = variables;
336 variables = n;
339 /* Create a fake field with the given type and name. NEXT is the next
340 field in the chain. */
342 static pair_p
343 create_field (pair_p next, type_p type, const char *name)
345 pair_p field;
347 field = XNEW (struct pair);
348 field->next = next;
349 field->type = type;
350 field->name = name;
351 field->opt = NULL;
352 field->line.file = __FILE__;
353 field->line.line = __LINE__;
354 return field;
357 /* Like create_field, but the field is only valid when condition COND
358 is true. */
360 static pair_p
361 create_optional_field (pair_p next, type_p type, const char *name,
362 const char *cond)
364 static int id = 1;
365 pair_p union_fields, field;
366 type_p union_type;
368 /* Create a fake union type with a single nameless field of type TYPE.
369 The field has a tag of "1". This allows us to make the presence
370 of a field of type TYPE depend on some boolean "desc" being true. */
371 union_fields = create_field (NULL, type, "");
372 union_fields->opt = create_option (union_fields->opt, "dot", "");
373 union_fields->opt = create_option (union_fields->opt, "tag", "1");
374 union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
375 &lexer_line, union_fields, NULL);
377 /* Create the field and give it the new fake union type. Add a "desc"
378 tag that specifies the condition under which the field is valid. */
379 field = create_field (next, union_type, name);
380 field->opt = create_option (field->opt, "desc", cond);
381 return field;
384 /* We don't care how long a CONST_DOUBLE is. */
385 #define CONST_DOUBLE_FORMAT "ww"
386 /* We don't want to see codes that are only for generator files. */
387 #undef GENERATOR_FILE
389 enum rtx_code {
390 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
391 #include "rtl.def"
392 #undef DEF_RTL_EXPR
393 NUM_RTX_CODE
396 static const char * const rtx_name[NUM_RTX_CODE] = {
397 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
398 #include "rtl.def"
399 #undef DEF_RTL_EXPR
402 static const char * const rtx_format[NUM_RTX_CODE] = {
403 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
404 #include "rtl.def"
405 #undef DEF_RTL_EXPR
408 static int rtx_next_new[NUM_RTX_CODE];
410 /* We also need codes and names for insn notes (not register notes).
411 Note that we do *not* bias the note values here. */
412 enum insn_note {
413 #define DEF_INSN_NOTE(NAME) NAME,
414 #include "insn-notes.def"
415 #undef DEF_INSN_NOTE
417 NOTE_INSN_MAX
420 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
421 default field for line number notes. */
422 static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
423 #define DEF_INSN_NOTE(NAME) #NAME,
424 #include "insn-notes.def"
425 #undef DEF_INSN_NOTE
428 #undef CONST_DOUBLE_FORMAT
429 #define GENERATOR_FILE
431 /* Generate the contents of the rtx_next array. This really doesn't belong
432 in gengtype at all, but it's needed for adjust_field_rtx_def. */
434 static void
435 gen_rtx_next (void)
437 int i;
438 for (i = 0; i < NUM_RTX_CODE; i++)
440 int k;
442 rtx_next_new[i] = -1;
443 if (strncmp (rtx_format[i], "iuu", 3) == 0)
444 rtx_next_new[i] = 2;
445 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
446 rtx_next_new[i] = 1;
447 else
448 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
449 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
450 rtx_next_new[i] = k;
454 /* Write out the contents of the rtx_next array. */
455 static void
456 write_rtx_next (void)
458 outf_p f = get_output_file_with_visibility (NULL);
459 int i;
461 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
462 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
463 for (i = 0; i < NUM_RTX_CODE; i++)
464 if (rtx_next_new[i] == -1)
465 oprintf (f, " 0,\n");
466 else
467 oprintf (f,
468 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
469 rtx_next_new[i]);
470 oprintf (f, "};\n");
473 /* Handle `special("rtx_def")'. This is a special case for field
474 `fld' of struct rtx_def, which is an array of unions whose values
475 are based in a complex way on the type of RTL. */
477 static type_p
478 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
480 pair_p flds = NULL;
481 options_p nodot;
482 int i;
483 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
484 type_p bitmap_tp, basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
486 if (t->kind != TYPE_UNION)
488 error_at_line (&lexer_line,
489 "special `rtx_def' must be applied to a union");
490 return &string_type;
493 nodot = create_option (NULL, "dot", "");
495 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
496 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
497 tree_tp = create_pointer (find_structure ("tree_node", 1));
498 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
499 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
500 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
501 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
502 constant_tp = create_pointer (find_structure ("constant_descriptor_rtx", 0));
503 scalar_tp = create_scalar_type ("rtunion scalar", 14);
506 pair_p note_flds = NULL;
507 int c;
509 for (c = 0; c <= NOTE_INSN_MAX; c++)
511 switch (c)
513 case NOTE_INSN_MAX:
514 note_flds = create_field (note_flds, &string_type, "rt_str");
515 break;
517 case NOTE_INSN_BLOCK_BEG:
518 case NOTE_INSN_BLOCK_END:
519 note_flds = create_field (note_flds, tree_tp, "rt_tree");
520 break;
522 case NOTE_INSN_VAR_LOCATION:
523 note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
524 break;
526 default:
527 note_flds = create_field (note_flds, scalar_tp, "rt_int");
528 break;
530 /* NOTE_INSN_MAX is used as the default field for line
531 number notes. */
532 if (c == NOTE_INSN_MAX)
533 note_flds->opt = create_option (nodot, "default", "");
534 else
535 note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
537 note_union_tp = new_structure ("rtx_def_note_subunion", 1,
538 &lexer_line, note_flds, NULL);
540 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */
542 pair_p sym_flds;
544 sym_flds = create_field (NULL, tree_tp, "rt_tree");
545 sym_flds->opt = create_option (nodot, "default", "");
547 sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
548 sym_flds->opt = create_option (nodot, "tag", "1");
550 symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
551 &lexer_line, sym_flds, NULL);
553 for (i = 0; i < NUM_RTX_CODE; i++)
555 pair_p subfields = NULL;
556 size_t aindex, nmindex;
557 const char *sname;
558 type_p substruct;
559 char *ftag;
561 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
563 type_p t;
564 const char *subname;
566 switch (rtx_format[i][aindex])
568 case '*':
569 case 'i':
570 case 'n':
571 case 'w':
572 t = scalar_tp;
573 subname = "rt_int";
574 break;
576 case '0':
577 if (i == MEM && aindex == 1)
578 t = mem_attrs_tp, subname = "rt_mem";
579 else if (i == JUMP_INSN && aindex == 9)
580 t = rtx_tp, subname = "rt_rtx";
581 else if (i == CODE_LABEL && aindex == 4)
582 t = scalar_tp, subname = "rt_int";
583 else if (i == CODE_LABEL && aindex == 5)
584 t = rtx_tp, subname = "rt_rtx";
585 else if (i == LABEL_REF
586 && (aindex == 1 || aindex == 2))
587 t = rtx_tp, subname = "rt_rtx";
588 else if (i == NOTE && aindex == 4)
589 t = note_union_tp, subname = "";
590 else if (i == NOTE && aindex >= 7)
591 t = scalar_tp, subname = "rt_int";
592 else if (i == ADDR_DIFF_VEC && aindex == 4)
593 t = scalar_tp, subname = "rt_int";
594 else if (i == VALUE && aindex == 0)
595 t = scalar_tp, subname = "rt_int";
596 else if (i == REG && aindex == 1)
597 t = scalar_tp, subname = "rt_int";
598 else if (i == REG && aindex == 2)
599 t = reg_attrs_tp, subname = "rt_reg";
600 else if (i == SCRATCH && aindex == 0)
601 t = scalar_tp, subname = "rt_int";
602 else if (i == SYMBOL_REF && aindex == 1)
603 t = scalar_tp, subname = "rt_int";
604 else if (i == SYMBOL_REF && aindex == 2)
605 t = symbol_union_tp, subname = "";
606 else if (i == BARRIER && aindex >= 3)
607 t = scalar_tp, subname = "rt_int";
608 else
610 error_at_line (&lexer_line,
611 "rtx type `%s' has `0' in position %lu, can't handle",
612 rtx_name[i], (unsigned long) aindex);
613 t = &string_type;
614 subname = "rt_int";
616 break;
618 case 's':
619 case 'S':
620 case 'T':
621 t = &string_type;
622 subname = "rt_str";
623 break;
625 case 'e':
626 case 'u':
627 t = rtx_tp;
628 subname = "rt_rtx";
629 break;
631 case 'E':
632 case 'V':
633 t = rtvec_tp;
634 subname = "rt_rtvec";
635 break;
637 case 't':
638 t = tree_tp;
639 subname = "rt_tree";
640 break;
642 case 'b':
643 t = bitmap_tp;
644 subname = "rt_bit";
645 break;
647 case 'B':
648 t = basic_block_tp;
649 subname = "rt_bb";
650 break;
652 default:
653 error_at_line (&lexer_line,
654 "rtx type `%s' has `%c' in position %lu, can't handle",
655 rtx_name[i], rtx_format[i][aindex],
656 (unsigned long)aindex);
657 t = &string_type;
658 subname = "rt_int";
659 break;
662 subfields = create_field (subfields, t,
663 xasprintf (".fld[%lu].%s",
664 (unsigned long) aindex,
665 subname));
666 subfields->opt = nodot;
667 if (t == note_union_tp)
668 subfields->opt = create_option (subfields->opt, "desc",
669 "NOTE_LINE_NUMBER (&%0)");
670 if (t == symbol_union_tp)
671 subfields->opt = create_option (subfields->opt, "desc",
672 "CONSTANT_POOL_ADDRESS_P (&%0)");
675 if (i == SYMBOL_REF)
677 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
678 type_p field_tp = find_structure ("block_symbol", 0);
679 subfields
680 = create_optional_field (subfields, field_tp, "block_sym",
681 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
684 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
685 substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
687 ftag = xstrdup (rtx_name[i]);
688 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
689 ftag[nmindex] = TOUPPER (ftag[nmindex]);
691 flds = create_field (flds, substruct, "");
692 flds->opt = create_option (nodot, "tag", ftag);
695 return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
698 /* Handle `special("tree_exp")'. This is a special case for
699 field `operands' of struct tree_exp, which although it claims to contain
700 pointers to trees, actually sometimes contains pointers to RTL too.
701 Passed T, the old type of the field, and OPT its options. Returns
702 a new type for the field. */
704 static type_p
705 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
707 pair_p flds;
708 options_p nodot;
710 if (t->kind != TYPE_ARRAY)
712 error_at_line (&lexer_line,
713 "special `tree_exp' must be applied to an array");
714 return &string_type;
717 nodot = create_option (NULL, "dot", "");
719 flds = create_field (NULL, t, "");
720 flds->opt = create_option (nodot, "length",
721 "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))");
722 flds->opt = create_option (flds->opt, "default", "");
724 return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
727 /* Perform any special processing on a type T, about to become the type
728 of a field. Return the appropriate type for the field.
729 At present:
730 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
731 - Similarly for arrays of pointer-to-char;
732 - Converts structures for which a parameter is provided to
733 TYPE_PARAM_STRUCT;
734 - Handles "special" options.
737 type_p
738 adjust_field_type (type_p t, options_p opt)
740 int length_p = 0;
741 const int pointer_p = t->kind == TYPE_POINTER;
742 type_p params[NUM_PARAM];
743 int params_p = 0;
744 int i;
746 for (i = 0; i < NUM_PARAM; i++)
747 params[i] = NULL;
749 for (; opt; opt = opt->next)
750 if (strcmp (opt->name, "length") == 0)
751 length_p = 1;
752 else if (strcmp (opt->name, "param_is") == 0
753 || (strncmp (opt->name, "param", 5) == 0
754 && ISDIGIT (opt->name[5])
755 && strcmp (opt->name + 6, "_is") == 0))
757 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
759 if (! UNION_OR_STRUCT_P (t)
760 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
762 error_at_line (&lexer_line,
763 "option `%s' may only be applied to structures or structure pointers",
764 opt->name);
765 return t;
768 params_p = 1;
769 if (params[num] != NULL)
770 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
771 if (! ISDIGIT (opt->name[5]))
772 params[num] = create_pointer ((type_p) opt->info);
773 else
774 params[num] = (type_p) opt->info;
776 else if (strcmp (opt->name, "special") == 0)
778 const char *special_name = opt->info;
779 if (strcmp (special_name, "tree_exp") == 0)
780 t = adjust_field_tree_exp (t, opt);
781 else if (strcmp (special_name, "rtx_def") == 0)
782 t = adjust_field_rtx_def (t, opt);
783 else
784 error_at_line (&lexer_line, "unknown special `%s'", special_name);
787 if (params_p)
789 type_p realt;
791 if (pointer_p)
792 t = t->u.p;
793 realt = find_param_structure (t, params);
794 t = pointer_p ? create_pointer (realt) : realt;
797 if (! length_p
798 && pointer_p
799 && t->u.p->kind == TYPE_SCALAR
800 && (strcmp (t->u.p->u.sc, "char") == 0
801 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
802 return &string_type;
803 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
804 && t->u.a.p->u.p->kind == TYPE_SCALAR
805 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
806 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
807 return create_array (&string_type, t->u.a.len);
809 return t;
812 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
813 and information about the correspondence between token types and fields
814 in TYPEINFO. POS is used for error messages. */
816 void
817 note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
818 struct fileloc *pos)
820 pair_p p;
821 pair_p *p_p;
823 for (p = typeinfo; p; p = p->next)
825 pair_p m;
827 if (p->name == NULL)
828 continue;
830 if (p->type == (type_p) 1)
832 pair_p pp;
833 int ok = 0;
835 for (pp = typeinfo; pp; pp = pp->next)
836 if (pp->type != (type_p) 1
837 && strcmp (pp->opt->info, p->opt->info) == 0)
839 ok = 1;
840 break;
842 if (! ok)
843 continue;
846 for (m = fields; m; m = m->next)
847 if (strcmp (m->name, p->name) == 0)
848 p->type = m->type;
849 if (p->type == NULL)
851 error_at_line (&p->line,
852 "couldn't match fieldname `%s'", p->name);
853 p->name = NULL;
857 p_p = &typeinfo;
858 while (*p_p)
860 pair_p p = *p_p;
862 if (p->name == NULL
863 || p->type == (type_p) 1)
864 *p_p = p->next;
865 else
866 p_p = &p->next;
869 do_typedef ("YYSTYPE", new_structure ("yy_union", 1, pos, typeinfo, o), pos);
872 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
873 static void set_gc_used (pair_p);
875 /* Handle OPT for set_gc_used_type. */
877 static void
878 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
879 int *pass_param, int *length, int *skip, type_p *nested_ptr)
881 options_p o;
882 for (o = opt; o; o = o->next)
883 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
884 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
885 else if (strcmp (o->name, "maybe_undef") == 0)
886 *maybe_undef = 1;
887 else if (strcmp (o->name, "use_params") == 0)
888 *pass_param = 1;
889 else if (strcmp (o->name, "length") == 0)
890 *length = 1;
891 else if (strcmp (o->name, "skip") == 0)
892 *skip = 1;
893 else if (strcmp (o->name, "nested_ptr") == 0)
894 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
897 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
899 static void
900 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
902 if (t->gc_used >= level)
903 return;
905 t->gc_used = level;
907 switch (t->kind)
909 case TYPE_STRUCT:
910 case TYPE_UNION:
912 pair_p f;
913 int dummy;
914 type_p dummy2;
916 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
917 &dummy2);
919 for (f = t->u.s.fields; f; f = f->next)
921 int maybe_undef = 0;
922 int pass_param = 0;
923 int length = 0;
924 int skip = 0;
925 type_p nested_ptr = NULL;
926 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
927 &length, &skip, &nested_ptr);
929 if (nested_ptr && f->type->kind == TYPE_POINTER)
930 set_gc_used_type (nested_ptr, GC_POINTED_TO,
931 pass_param ? param : NULL);
932 else if (length && f->type->kind == TYPE_POINTER)
933 set_gc_used_type (f->type->u.p, GC_USED, NULL);
934 else if (maybe_undef && f->type->kind == TYPE_POINTER)
935 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
936 else if (pass_param && f->type->kind == TYPE_POINTER && param)
937 set_gc_used_type (find_param_structure (f->type->u.p, param),
938 GC_POINTED_TO, NULL);
939 else if (skip)
940 ; /* target type is not used through this field */
941 else
942 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
944 break;
947 case TYPE_POINTER:
948 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
949 break;
951 case TYPE_ARRAY:
952 set_gc_used_type (t->u.a.p, GC_USED, param);
953 break;
955 case TYPE_LANG_STRUCT:
956 for (t = t->u.s.lang_struct; t; t = t->next)
957 set_gc_used_type (t, level, param);
958 break;
960 case TYPE_PARAM_STRUCT:
962 int i;
963 for (i = 0; i < NUM_PARAM; i++)
964 if (t->u.param_struct.param[i] != 0)
965 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
967 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
968 level = GC_POINTED_TO;
969 else
970 level = GC_USED;
971 t->u.param_struct.stru->gc_used = GC_UNUSED;
972 set_gc_used_type (t->u.param_struct.stru, level,
973 t->u.param_struct.param);
974 break;
976 default:
977 break;
981 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
983 static void
984 set_gc_used (pair_p variables)
986 pair_p p;
987 for (p = variables; p; p = p->next)
988 set_gc_used_type (p->type, GC_USED, NULL);
991 /* File mapping routines. For each input file, there is one output .c file
992 (but some output files have many input files), and there is one .h file
993 for the whole build. */
995 /* The list of output files. */
996 static outf_p output_files;
998 /* The output header file that is included into pretty much every
999 source file. */
1000 static outf_p header_file;
1002 /* Number of files specified in gtfiles. */
1003 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1005 /* Number of files in the language files array. */
1006 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1008 /* Length of srcdir name. */
1009 static int srcdir_len = 0;
1011 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1012 outf_p base_files[NUM_BASE_FILES];
1014 static outf_p create_file (const char *, const char *);
1015 static const char * get_file_basename (const char *);
1017 /* Create and return an outf_p for a new file for NAME, to be called
1018 ONAME. */
1020 static outf_p
1021 create_file (const char *name, const char *oname)
1023 static const char *const hdr[] = {
1024 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
1025 "\n",
1026 "This file is part of GCC.\n",
1027 "\n",
1028 "GCC is free software; you can redistribute it and/or modify it under\n",
1029 "the terms of the GNU General Public License as published by the Free\n",
1030 "Software Foundation; either version 2, or (at your option) any later\n",
1031 "version.\n",
1032 "\n",
1033 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1034 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1035 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1036 "for more details.\n",
1037 "\n",
1038 "You should have received a copy of the GNU General Public License\n",
1039 "along with GCC; see the file COPYING. If not, write to the Free\n",
1040 "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1041 "02110-1301, USA. */\n",
1042 "\n",
1043 "/* This file is machine generated. Do not edit. */\n"
1045 outf_p f;
1046 size_t i;
1048 f = XCNEW (struct outf);
1049 f->next = output_files;
1050 f->name = oname;
1051 output_files = f;
1053 oprintf (f, "/* Type information for %s.\n", name);
1054 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1055 oprintf (f, "%s", hdr[i]);
1056 return f;
1059 /* Print, like fprintf, to O. */
1060 void
1061 oprintf (outf_p o, const char *format, ...)
1063 char *s;
1064 size_t slength;
1065 va_list ap;
1067 va_start (ap, format);
1068 slength = xvasprintf (&s, format, ap);
1070 if (o->bufused + slength > o->buflength)
1072 size_t new_len = o->buflength;
1073 if (new_len == 0)
1074 new_len = 1024;
1075 do {
1076 new_len *= 2;
1077 } while (o->bufused + slength >= new_len);
1078 o->buf = XRESIZEVEC (char, o->buf, new_len);
1079 o->buflength = new_len;
1081 memcpy (o->buf + o->bufused, s, slength);
1082 o->bufused += slength;
1083 free (s);
1084 va_end (ap);
1087 /* Open the global header file and the language-specific header files. */
1089 static void
1090 open_base_files (void)
1092 size_t i;
1094 header_file = create_file ("GCC", "gtype-desc.h");
1096 for (i = 0; i < NUM_BASE_FILES; i++)
1097 base_files[i] = create_file (lang_dir_names[i],
1098 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1100 /* gtype-desc.c is a little special, so we create it here. */
1102 /* The order of files here matters very much. */
1103 static const char *const ifiles [] = {
1104 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1105 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1106 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1107 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1108 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1109 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1110 "except.h", "output.h", NULL
1112 const char *const *ifp;
1113 outf_p gtype_desc_c;
1115 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1116 for (ifp = ifiles; *ifp; ifp++)
1117 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1121 /* Determine the pathname to F relative to $(srcdir). */
1123 static const char *
1124 get_file_basename (const char *f)
1126 const char *basename;
1127 unsigned i;
1129 basename = strrchr (f, '/');
1131 if (!basename)
1132 return f;
1134 basename++;
1136 for (i = 1; i < NUM_BASE_FILES; i++)
1138 const char * s1;
1139 const char * s2;
1140 int l1;
1141 int l2;
1142 s1 = basename - strlen (lang_dir_names [i]) - 1;
1143 s2 = lang_dir_names [i];
1144 l1 = strlen (s1);
1145 l2 = strlen (s2);
1146 if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1148 basename -= l2 + 1;
1149 if ((basename - f - 1) != srcdir_len)
1150 fatal ("filename `%s' should be preceded by $srcdir", f);
1151 break;
1155 return basename;
1158 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1159 INPUT_FILE is used by <lang>.
1161 This function should be written to assume that a file _is_ used
1162 if the situation is unclear. If it wrongly assumes a file _is_ used,
1163 a linker error will result. If it wrongly assumes a file _is not_ used,
1164 some GC roots may be missed, which is a much harder-to-debug problem. */
1166 unsigned
1167 get_base_file_bitmap (const char *input_file)
1169 const char *basename = get_file_basename (input_file);
1170 const char *slashpos = strchr (basename, '/');
1171 unsigned j;
1172 unsigned k;
1173 unsigned bitmap;
1175 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1176 it belongs to the corresponding language. The file may belong to other
1177 languages as well (which is checked for below). */
1179 if (slashpos)
1181 size_t i;
1182 for (i = 1; i < NUM_BASE_FILES; i++)
1183 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1184 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1186 /* It's in a language directory, set that language. */
1187 bitmap = 1 << i;
1191 /* If it's in any config-lang.in, then set for the languages
1192 specified. */
1194 bitmap = 0;
1196 for (j = 0; j < NUM_LANG_FILES; j++)
1198 if (!strcmp(input_file, lang_files[j]))
1200 for (k = 0; k < NUM_BASE_FILES; k++)
1202 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1203 bitmap |= (1 << k);
1208 /* Otherwise, set all languages. */
1209 if (!bitmap)
1210 bitmap = (1 << NUM_BASE_FILES) - 1;
1212 return bitmap;
1215 /* An output file, suitable for definitions, that can see declarations
1216 made in INPUT_FILE and is linked into every language that uses
1217 INPUT_FILE. */
1219 outf_p
1220 get_output_file_with_visibility (const char *input_file)
1222 outf_p r;
1223 size_t len;
1224 const char *basename;
1225 const char *for_name;
1226 const char *output_name;
1228 /* This can happen when we need a file with visibility on a
1229 structure that we've never seen. We have to just hope that it's
1230 globally visible. */
1231 if (input_file == NULL)
1232 input_file = "system.h";
1234 /* Determine the output file name. */
1235 basename = get_file_basename (input_file);
1237 len = strlen (basename);
1238 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1239 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1240 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1242 char *s;
1244 output_name = s = xasprintf ("gt-%s", basename);
1245 for (; *s != '.'; s++)
1246 if (! ISALNUM (*s) && *s != '-')
1247 *s = '-';
1248 memcpy (s, ".h", sizeof (".h"));
1249 for_name = basename;
1251 /* Some headers get used by more than one front-end; hence, it
1252 would be inappropriate to spew them out to a single gtype-<lang>.h
1253 (and gengtype doesn't know how to direct spewage into multiple
1254 gtype-<lang>.h headers at this time). Instead, we pair up these
1255 headers with source files (and their special purpose gt-*.h headers). */
1256 else if (strcmp (basename, "c-common.h") == 0)
1257 output_name = "gt-c-common.h", for_name = "c-common.c";
1258 else if (strcmp (basename, "c-tree.h") == 0)
1259 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1260 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1261 && strcmp (basename + 3, "cp-tree.h") == 0)
1262 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1263 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1264 && strcmp (basename + 3, "decl.h") == 0)
1265 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1266 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1267 && strcmp (basename + 3, "name-lookup.h") == 0)
1268 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1269 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1270 && strcmp (basename + 5, "objc-act.h") == 0)
1271 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1272 else
1274 size_t i;
1276 for (i = 0; i < NUM_BASE_FILES; i++)
1277 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1278 && basename[strlen(lang_dir_names[i])] == '/')
1279 return base_files[i];
1281 output_name = "gtype-desc.c";
1282 for_name = NULL;
1285 /* Look through to see if we've ever seen this output filename before. */
1286 for (r = output_files; r; r = r->next)
1287 if (strcmp (r->name, output_name) == 0)
1288 return r;
1290 /* If not, create it. */
1291 r = create_file (for_name, output_name);
1293 return r;
1296 /* The name of an output file, suitable for definitions, that can see
1297 declarations made in INPUT_FILE and is linked into every language
1298 that uses INPUT_FILE. */
1300 const char *
1301 get_output_file_name (const char *input_file)
1303 return get_output_file_with_visibility (input_file)->name;
1306 /* Copy the output to its final destination,
1307 but don't unnecessarily change modification times. */
1309 static void
1310 close_output_files (void)
1312 outf_p of;
1314 for (of = output_files; of; of = of->next)
1316 FILE * newfile;
1318 newfile = fopen (of->name, "r");
1319 if (newfile != NULL )
1321 int no_write_p;
1322 size_t i;
1324 for (i = 0; i < of->bufused; i++)
1326 int ch;
1327 ch = fgetc (newfile);
1328 if (ch == EOF || ch != (unsigned char) of->buf[i])
1329 break;
1331 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1332 fclose (newfile);
1334 if (no_write_p)
1335 continue;
1338 newfile = fopen (of->name, "w");
1339 if (newfile == NULL)
1341 perror ("opening output file");
1342 exit (1);
1344 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1346 perror ("writing output file");
1347 exit (1);
1349 if (fclose (newfile) != 0)
1351 perror ("closing output file");
1352 exit (1);
1357 struct flist {
1358 struct flist *next;
1359 int started_p;
1360 const char *name;
1361 outf_p f;
1364 struct walk_type_data;
1366 /* For scalars and strings, given the item in 'val'.
1367 For structures, given a pointer to the item in 'val'.
1368 For misc. pointers, given the item in 'val'.
1370 typedef void (*process_field_fn)
1371 (type_p f, const struct walk_type_data *p);
1372 typedef void (*func_name_fn)
1373 (type_p s, const struct walk_type_data *p);
1375 /* Parameters for write_types. */
1377 struct write_types_data
1379 const char *prefix;
1380 const char *param_prefix;
1381 const char *subfield_marker_routine;
1382 const char *marker_routine;
1383 const char *reorder_note_routine;
1384 const char *comment;
1387 static void output_escaped_param (struct walk_type_data *d,
1388 const char *, const char *);
1389 static void output_mangled_typename (outf_p, type_p);
1390 static void walk_type (type_p t, struct walk_type_data *d);
1391 static void write_func_for_structure
1392 (type_p orig_s, type_p s, type_p * param,
1393 const struct write_types_data *wtd);
1394 static void write_types_process_field
1395 (type_p f, const struct walk_type_data *d);
1396 static void write_types (type_p structures,
1397 type_p param_structs,
1398 const struct write_types_data *wtd);
1399 static void write_types_local_process_field
1400 (type_p f, const struct walk_type_data *d);
1401 static void write_local_func_for_structure
1402 (type_p orig_s, type_p s, type_p * param);
1403 static void write_local (type_p structures,
1404 type_p param_structs);
1405 static void write_enum_defn (type_p structures, type_p param_structs);
1406 static int contains_scalar_p (type_p t);
1407 static void put_mangled_filename (outf_p , const char *);
1408 static void finish_root_table (struct flist *flp, const char *pfx,
1409 const char *tname, const char *lastname,
1410 const char *name);
1411 static void write_root (outf_p , pair_p, type_p, const char *, int,
1412 struct fileloc *, const char *);
1413 static void write_array (outf_p f, pair_p v,
1414 const struct write_types_data *wtd);
1415 static void write_roots (pair_p);
1417 /* Parameters for walk_type. */
1419 struct walk_type_data
1421 process_field_fn process_field;
1422 const void *cookie;
1423 outf_p of;
1424 options_p opt;
1425 const char *val;
1426 const char *prev_val[4];
1427 int indent;
1428 int counter;
1429 struct fileloc *line;
1430 lang_bitmap bitmap;
1431 type_p *param;
1432 int used_length;
1433 type_p orig_s;
1434 const char *reorder_fn;
1435 bool needs_cast_p;
1436 bool fn_wants_lvalue;
1439 /* Print a mangled name representing T to OF. */
1441 static void
1442 output_mangled_typename (outf_p of, type_p t)
1444 if (t == NULL)
1445 oprintf (of, "Z");
1446 else switch (t->kind)
1448 case TYPE_POINTER:
1449 oprintf (of, "P");
1450 output_mangled_typename (of, t->u.p);
1451 break;
1452 case TYPE_SCALAR:
1453 oprintf (of, "I");
1454 break;
1455 case TYPE_STRING:
1456 oprintf (of, "S");
1457 break;
1458 case TYPE_STRUCT:
1459 case TYPE_UNION:
1460 case TYPE_LANG_STRUCT:
1461 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1462 break;
1463 case TYPE_PARAM_STRUCT:
1465 int i;
1466 for (i = 0; i < NUM_PARAM; i++)
1467 if (t->u.param_struct.param[i] != NULL)
1468 output_mangled_typename (of, t->u.param_struct.param[i]);
1469 output_mangled_typename (of, t->u.param_struct.stru);
1471 break;
1472 case TYPE_ARRAY:
1473 gcc_unreachable ();
1477 /* Print PARAM to D->OF processing escapes. D->VAL references the
1478 current object, D->PREV_VAL the object containing the current
1479 object, ONAME is the name of the option and D->LINE is used to
1480 print error messages. */
1482 static void
1483 output_escaped_param (struct walk_type_data *d, const char *param,
1484 const char *oname)
1486 const char *p;
1488 for (p = param; *p; p++)
1489 if (*p != '%')
1490 oprintf (d->of, "%c", *p);
1491 else switch (*++p)
1493 case 'h':
1494 oprintf (d->of, "(%s)", d->prev_val[2]);
1495 break;
1496 case '0':
1497 oprintf (d->of, "(%s)", d->prev_val[0]);
1498 break;
1499 case '1':
1500 oprintf (d->of, "(%s)", d->prev_val[1]);
1501 break;
1502 case 'a':
1504 const char *pp = d->val + strlen (d->val);
1505 while (pp[-1] == ']')
1506 while (*pp != '[')
1507 pp--;
1508 oprintf (d->of, "%s", pp);
1510 break;
1511 default:
1512 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1513 oname, '%', *p);
1517 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1518 which is of type T. Write code to D->OF to constrain execution (at
1519 the point that D->PROCESS_FIELD is called) to the appropriate
1520 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1521 pointers to those objects. D->PREV_VAL lists the objects
1522 containing the current object, D->OPT is a list of options to
1523 apply, D->INDENT is the current indentation level, D->LINE is used
1524 to print error messages, D->BITMAP indicates which languages to
1525 print the structure for, and D->PARAM is the current parameter
1526 (from an enclosing param_is option). */
1528 static void
1529 walk_type (type_p t, struct walk_type_data *d)
1531 const char *length = NULL;
1532 const char *desc = NULL;
1533 int maybe_undef_p = 0;
1534 int use_param_num = -1;
1535 int use_params_p = 0;
1536 options_p oo;
1537 const struct nested_ptr_data *nested_ptr_d = NULL;
1539 d->needs_cast_p = false;
1540 for (oo = d->opt; oo; oo = oo->next)
1541 if (strcmp (oo->name, "length") == 0)
1542 length = oo->info;
1543 else if (strcmp (oo->name, "maybe_undef") == 0)
1544 maybe_undef_p = 1;
1545 else if (strncmp (oo->name, "use_param", 9) == 0
1546 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1547 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1548 else if (strcmp (oo->name, "use_params") == 0)
1549 use_params_p = 1;
1550 else if (strcmp (oo->name, "desc") == 0)
1551 desc = oo->info;
1552 else if (strcmp (oo->name, "nested_ptr") == 0)
1553 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1554 else if (strcmp (oo->name, "dot") == 0)
1556 else if (strcmp (oo->name, "tag") == 0)
1558 else if (strcmp (oo->name, "special") == 0)
1560 else if (strcmp (oo->name, "skip") == 0)
1562 else if (strcmp (oo->name, "default") == 0)
1564 else if (strcmp (oo->name, "descbits") == 0)
1566 else if (strcmp (oo->name, "param_is") == 0)
1568 else if (strncmp (oo->name, "param", 5) == 0
1569 && ISDIGIT (oo->name[5])
1570 && strcmp (oo->name + 6, "_is") == 0)
1572 else if (strcmp (oo->name, "chain_next") == 0)
1574 else if (strcmp (oo->name, "chain_prev") == 0)
1576 else if (strcmp (oo->name, "reorder") == 0)
1578 else
1579 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1581 if (d->used_length)
1582 length = NULL;
1584 if (use_params_p)
1586 int pointer_p = t->kind == TYPE_POINTER;
1588 if (pointer_p)
1589 t = t->u.p;
1590 if (! UNION_OR_STRUCT_P (t))
1591 error_at_line (d->line, "`use_params' option on unimplemented type");
1592 else
1593 t = find_param_structure (t, d->param);
1594 if (pointer_p)
1595 t = create_pointer (t);
1598 if (use_param_num != -1)
1600 if (d->param != NULL && d->param[use_param_num] != NULL)
1602 type_p nt = d->param[use_param_num];
1604 if (t->kind == TYPE_ARRAY)
1605 nt = create_array (nt, t->u.a.len);
1606 else if (length != NULL && t->kind == TYPE_POINTER)
1607 nt = create_pointer (nt);
1608 d->needs_cast_p = (t->kind != TYPE_POINTER
1609 && (nt->kind == TYPE_POINTER
1610 || nt->kind == TYPE_STRING));
1611 t = nt;
1613 else
1614 error_at_line (d->line, "no parameter defined for `%s'",
1615 d->val);
1618 if (maybe_undef_p
1619 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1621 error_at_line (d->line,
1622 "field `%s' has invalid option `maybe_undef_p'\n",
1623 d->val);
1624 return;
1627 switch (t->kind)
1629 case TYPE_SCALAR:
1630 case TYPE_STRING:
1631 d->process_field (t, d);
1632 break;
1634 case TYPE_POINTER:
1636 if (maybe_undef_p
1637 && t->u.p->u.s.line.file == NULL)
1639 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1640 break;
1643 if (! length)
1645 if (! UNION_OR_STRUCT_P (t->u.p)
1646 && t->u.p->kind != TYPE_PARAM_STRUCT)
1648 error_at_line (d->line,
1649 "field `%s' is pointer to unimplemented type",
1650 d->val);
1651 break;
1654 if (nested_ptr_d)
1656 const char *oldprevval2 = d->prev_val[2];
1658 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1660 error_at_line (d->line,
1661 "field `%s' has invalid "
1662 "option `nested_ptr'\n",
1663 d->val);
1664 return;
1667 d->prev_val[2] = d->val;
1668 oprintf (d->of, "%*s{\n", d->indent, "");
1669 d->indent += 2;
1670 d->val = xasprintf ("x%d", d->counter++);
1671 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1672 (nested_ptr_d->type->kind == TYPE_UNION
1673 ? "union" : "struct"),
1674 nested_ptr_d->type->u.s.tag,
1675 d->fn_wants_lvalue ? "" : "const ",
1676 d->val);
1677 oprintf (d->of, "%*s", d->indent + 2, "");
1678 output_escaped_param (d, nested_ptr_d->convert_from,
1679 "nested_ptr");
1680 oprintf (d->of, ";\n");
1682 d->process_field (nested_ptr_d->type, d);
1684 if (d->fn_wants_lvalue)
1686 oprintf (d->of, "%*s%s = ", d->indent, "",
1687 d->prev_val[2]);
1688 d->prev_val[2] = d->val;
1689 output_escaped_param (d, nested_ptr_d->convert_to,
1690 "nested_ptr");
1691 oprintf (d->of, ";\n");
1694 d->indent -= 2;
1695 oprintf (d->of, "%*s}\n", d->indent, "");
1696 d->val = d->prev_val[2];
1697 d->prev_val[2] = oldprevval2;
1699 else
1700 d->process_field (t->u.p, d);
1702 else
1704 int loopcounter = d->counter++;
1705 const char *oldval = d->val;
1706 const char *oldprevval3 = d->prev_val[3];
1707 char *newval;
1709 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1710 d->indent += 2;
1711 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1712 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1713 loopcounter, loopcounter);
1714 output_escaped_param (d, length, "length");
1715 oprintf (d->of, "); i%d++) {\n", loopcounter);
1716 d->indent += 2;
1717 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1718 d->used_length = 1;
1719 d->prev_val[3] = oldval;
1720 walk_type (t->u.p, d);
1721 free (newval);
1722 d->val = oldval;
1723 d->prev_val[3] = oldprevval3;
1724 d->used_length = 0;
1725 d->indent -= 2;
1726 oprintf (d->of, "%*s}\n", d->indent, "");
1727 d->process_field(t, d);
1728 d->indent -= 2;
1729 oprintf (d->of, "%*s}\n", d->indent, "");
1732 break;
1734 case TYPE_ARRAY:
1736 int loopcounter = d->counter++;
1737 const char *oldval = d->val;
1738 char *newval;
1740 /* If it's an array of scalars, we optimize by not generating
1741 any code. */
1742 if (t->u.a.p->kind == TYPE_SCALAR)
1743 break;
1745 oprintf (d->of, "%*s{\n", d->indent, "");
1746 d->indent += 2;
1747 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1748 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1749 loopcounter, loopcounter);
1750 if (length)
1751 output_escaped_param (d, length, "length");
1752 else
1753 oprintf (d->of, "%s", t->u.a.len);
1754 oprintf (d->of, "); i%d++) {\n", loopcounter);
1755 d->indent += 2;
1756 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1757 d->used_length = 1;
1758 walk_type (t->u.a.p, d);
1759 free (newval);
1760 d->used_length = 0;
1761 d->val = oldval;
1762 d->indent -= 2;
1763 oprintf (d->of, "%*s}\n", d->indent, "");
1764 d->indent -= 2;
1765 oprintf (d->of, "%*s}\n", d->indent, "");
1767 break;
1769 case TYPE_STRUCT:
1770 case TYPE_UNION:
1772 pair_p f;
1773 const char *oldval = d->val;
1774 const char *oldprevval1 = d->prev_val[1];
1775 const char *oldprevval2 = d->prev_val[2];
1776 const int union_p = t->kind == TYPE_UNION;
1777 int seen_default_p = 0;
1778 options_p o;
1780 if (! t->u.s.line.file)
1781 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1783 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1785 error_at_line (d->line,
1786 "structure `%s' defined for mismatching languages",
1787 t->u.s.tag);
1788 error_at_line (&t->u.s.line, "one structure defined here");
1791 /* Some things may also be defined in the structure's options. */
1792 for (o = t->u.s.opt; o; o = o->next)
1793 if (! desc && strcmp (o->name, "desc") == 0)
1794 desc = o->info;
1796 d->prev_val[2] = oldval;
1797 d->prev_val[1] = oldprevval2;
1798 if (union_p)
1800 if (desc == NULL)
1802 error_at_line (d->line, "missing `desc' option for union `%s'",
1803 t->u.s.tag);
1804 desc = "1";
1806 oprintf (d->of, "%*sswitch (", d->indent, "");
1807 output_escaped_param (d, desc, "desc");
1808 oprintf (d->of, ")\n");
1809 d->indent += 2;
1810 oprintf (d->of, "%*s{\n", d->indent, "");
1812 for (f = t->u.s.fields; f; f = f->next)
1814 options_p oo;
1815 const char *dot = ".";
1816 const char *tagid = NULL;
1817 int skip_p = 0;
1818 int default_p = 0;
1819 int use_param_p = 0;
1820 char *newval;
1822 d->reorder_fn = NULL;
1823 for (oo = f->opt; oo; oo = oo->next)
1824 if (strcmp (oo->name, "dot") == 0)
1825 dot = oo->info;
1826 else if (strcmp (oo->name, "tag") == 0)
1827 tagid = oo->info;
1828 else if (strcmp (oo->name, "skip") == 0)
1829 skip_p = 1;
1830 else if (strcmp (oo->name, "default") == 0)
1831 default_p = 1;
1832 else if (strcmp (oo->name, "reorder") == 0)
1833 d->reorder_fn = oo->info;
1834 else if (strncmp (oo->name, "use_param", 9) == 0
1835 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1836 use_param_p = 1;
1838 if (skip_p)
1839 continue;
1841 if (union_p && tagid)
1843 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1844 d->indent += 2;
1846 else if (union_p && default_p)
1848 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1849 d->indent += 2;
1850 seen_default_p = 1;
1852 else if (! union_p && (default_p || tagid))
1853 error_at_line (d->line,
1854 "can't use `%s' outside a union on field `%s'",
1855 default_p ? "default" : "tag", f->name);
1856 else if (union_p && ! (default_p || tagid)
1857 && f->type->kind == TYPE_SCALAR)
1859 fprintf (stderr,
1860 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1861 d->line->file, d->line->line, f->name);
1862 continue;
1864 else if (union_p && ! (default_p || tagid))
1865 error_at_line (d->line,
1866 "field `%s' is missing `tag' or `default' option",
1867 f->name);
1869 d->line = &f->line;
1870 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1871 d->opt = f->opt;
1872 d->used_length = false;
1874 if (union_p && use_param_p && d->param == NULL)
1875 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1876 else
1877 walk_type (f->type, d);
1879 free (newval);
1881 if (union_p)
1883 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1884 d->indent -= 2;
1887 d->reorder_fn = NULL;
1889 d->val = oldval;
1890 d->prev_val[1] = oldprevval1;
1891 d->prev_val[2] = oldprevval2;
1893 if (union_p && ! seen_default_p)
1895 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1896 oprintf (d->of, "%*s break;\n", d->indent, "");
1898 if (union_p)
1900 oprintf (d->of, "%*s}\n", d->indent, "");
1901 d->indent -= 2;
1904 break;
1906 case TYPE_LANG_STRUCT:
1908 type_p nt;
1909 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1910 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1911 break;
1912 if (nt == NULL)
1913 error_at_line (d->line, "structure `%s' differs between languages",
1914 t->u.s.tag);
1915 else
1916 walk_type (nt, d);
1918 break;
1920 case TYPE_PARAM_STRUCT:
1922 type_p *oldparam = d->param;
1924 d->param = t->u.param_struct.param;
1925 walk_type (t->u.param_struct.stru, d);
1926 d->param = oldparam;
1928 break;
1930 default:
1931 gcc_unreachable ();
1935 /* process_field routine for marking routines. */
1937 static void
1938 write_types_process_field (type_p f, const struct walk_type_data *d)
1940 const struct write_types_data *wtd;
1941 const char *cast = d->needs_cast_p ? "(void *)" : "";
1942 wtd = (const struct write_types_data *) d->cookie;
1944 switch (f->kind)
1946 case TYPE_POINTER:
1947 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1948 wtd->subfield_marker_routine, cast, d->val);
1949 if (wtd->param_prefix)
1951 oprintf (d->of, ", %s", d->prev_val[3]);
1952 if (d->orig_s)
1954 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1955 output_mangled_typename (d->of, d->orig_s);
1957 else
1958 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1960 if (f->u.p->kind == TYPE_PARAM_STRUCT
1961 && f->u.p->u.s.line.file != NULL)
1963 oprintf (d->of, ", gt_e_");
1964 output_mangled_typename (d->of, f);
1966 else if (UNION_OR_STRUCT_P (f)
1967 && f->u.p->u.s.line.file != NULL)
1969 oprintf (d->of, ", gt_ggc_e_");
1970 output_mangled_typename (d->of, f);
1972 else
1973 oprintf (d->of, ", gt_types_enum_last");
1975 oprintf (d->of, ");\n");
1976 if (d->reorder_fn && wtd->reorder_note_routine)
1977 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1978 wtd->reorder_note_routine, cast, d->val,
1979 d->prev_val[3], d->reorder_fn);
1980 break;
1982 case TYPE_STRING:
1983 if (wtd->param_prefix == NULL)
1984 break;
1986 case TYPE_STRUCT:
1987 case TYPE_UNION:
1988 case TYPE_LANG_STRUCT:
1989 case TYPE_PARAM_STRUCT:
1990 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1991 output_mangled_typename (d->of, f);
1992 oprintf (d->of, " (%s%s);\n", cast, d->val);
1993 if (d->reorder_fn && wtd->reorder_note_routine)
1994 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1995 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1996 d->reorder_fn);
1997 break;
1999 case TYPE_SCALAR:
2000 break;
2002 default:
2003 gcc_unreachable ();
2007 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
2009 static void
2010 output_type_enum (outf_p of, type_p s)
2012 if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2014 oprintf (of, ", gt_e_");
2015 output_mangled_typename (of, s);
2017 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2019 oprintf (of, ", gt_ggc_e_");
2020 output_mangled_typename (of, s);
2022 else
2023 oprintf (of, ", gt_types_enum_last");
2026 /* For S, a structure that's part of ORIG_S, and using parameters
2027 PARAM, write out a routine that:
2028 - Takes a parameter, a void * but actually of type *S
2029 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2030 field of S or its substructures and (in some cases) things
2031 that are pointed to by S.
2034 static void
2035 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2036 const struct write_types_data *wtd)
2038 const char *fn = s->u.s.line.file;
2039 int i;
2040 const char *chain_next = NULL;
2041 const char *chain_prev = NULL;
2042 options_p opt;
2043 struct walk_type_data d;
2045 /* This is a hack, and not the good kind either. */
2046 for (i = NUM_PARAM - 1; i >= 0; i--)
2047 if (param && param[i] && param[i]->kind == TYPE_POINTER
2048 && UNION_OR_STRUCT_P (param[i]->u.p))
2049 fn = param[i]->u.p->u.s.line.file;
2051 memset (&d, 0, sizeof (d));
2052 d.of = get_output_file_with_visibility (fn);
2054 for (opt = s->u.s.opt; opt; opt = opt->next)
2055 if (strcmp (opt->name, "chain_next") == 0)
2056 chain_next = opt->info;
2057 else if (strcmp (opt->name, "chain_prev") == 0)
2058 chain_prev = opt->info;
2060 if (chain_prev != NULL && chain_next == NULL)
2061 error_at_line (&s->u.s.line, "chain_prev without chain_next");
2063 d.process_field = write_types_process_field;
2064 d.cookie = wtd;
2065 d.orig_s = orig_s;
2066 d.opt = s->u.s.opt;
2067 d.line = &s->u.s.line;
2068 d.bitmap = s->u.s.bitmap;
2069 d.param = param;
2070 d.prev_val[0] = "*x";
2071 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2072 d.prev_val[3] = "x";
2073 d.val = "(*x)";
2075 oprintf (d.of, "\n");
2076 oprintf (d.of, "void\n");
2077 if (param == NULL)
2078 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2079 else
2081 oprintf (d.of, "gt_%s_", wtd->prefix);
2082 output_mangled_typename (d.of, orig_s);
2084 oprintf (d.of, " (void *x_p)\n");
2085 oprintf (d.of, "{\n");
2086 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2087 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2088 chain_next == NULL ? "const " : "",
2089 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2090 if (chain_next != NULL)
2091 oprintf (d.of, " %s %s * xlimit = x;\n",
2092 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2093 if (chain_next == NULL)
2095 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2096 if (wtd->param_prefix)
2098 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2099 output_mangled_typename (d.of, orig_s);
2100 output_type_enum (d.of, orig_s);
2102 oprintf (d.of, "))\n");
2104 else
2106 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2107 if (wtd->param_prefix)
2109 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2110 output_mangled_typename (d.of, orig_s);
2111 output_type_enum (d.of, orig_s);
2113 oprintf (d.of, "))\n");
2114 oprintf (d.of, " xlimit = (");
2115 d.prev_val[2] = "*xlimit";
2116 output_escaped_param (&d, chain_next, "chain_next");
2117 oprintf (d.of, ");\n");
2118 if (chain_prev != NULL)
2120 oprintf (d.of, " if (x != xlimit)\n");
2121 oprintf (d.of, " for (;;)\n");
2122 oprintf (d.of, " {\n");
2123 oprintf (d.of, " %s %s * const xprev = (",
2124 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2126 d.prev_val[2] = "*x";
2127 output_escaped_param (&d, chain_prev, "chain_prev");
2128 oprintf (d.of, ");\n");
2129 oprintf (d.of, " if (xprev == NULL) break;\n");
2130 oprintf (d.of, " x = xprev;\n");
2131 oprintf (d.of, " (void) %s (xprev",
2132 wtd->marker_routine);
2133 if (wtd->param_prefix)
2135 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2136 output_mangled_typename (d.of, orig_s);
2137 output_type_enum (d.of, orig_s);
2139 oprintf (d.of, ");\n");
2140 oprintf (d.of, " }\n");
2142 oprintf (d.of, " while (x != xlimit)\n");
2144 oprintf (d.of, " {\n");
2146 d.prev_val[2] = "*x";
2147 d.indent = 6;
2148 walk_type (s, &d);
2150 if (chain_next != NULL)
2152 oprintf (d.of, " x = (");
2153 output_escaped_param (&d, chain_next, "chain_next");
2154 oprintf (d.of, ");\n");
2157 oprintf (d.of, " }\n");
2158 oprintf (d.of, "}\n");
2161 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2163 static void
2164 write_types (type_p structures, type_p param_structs,
2165 const struct write_types_data *wtd)
2167 type_p s;
2169 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2170 for (s = structures; s; s = s->next)
2171 if (s->gc_used == GC_POINTED_TO
2172 || s->gc_used == GC_MAYBE_POINTED_TO)
2174 options_p opt;
2176 if (s->gc_used == GC_MAYBE_POINTED_TO
2177 && s->u.s.line.file == NULL)
2178 continue;
2180 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2181 output_mangled_typename (header_file, s);
2182 oprintf (header_file, "(X) do { \\\n");
2183 oprintf (header_file,
2184 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2185 s->u.s.tag);
2186 oprintf (header_file,
2187 " } while (0)\n");
2189 for (opt = s->u.s.opt; opt; opt = opt->next)
2190 if (strcmp (opt->name, "ptr_alias") == 0)
2192 type_p t = (type_p) opt->info;
2193 if (t->kind == TYPE_STRUCT
2194 || t->kind == TYPE_UNION
2195 || t->kind == TYPE_LANG_STRUCT)
2196 oprintf (header_file,
2197 "#define gt_%sx_%s gt_%sx_%s\n",
2198 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2199 else
2200 error_at_line (&s->u.s.line,
2201 "structure alias is not a structure");
2202 break;
2204 if (opt)
2205 continue;
2207 /* Declare the marker procedure only once. */
2208 oprintf (header_file,
2209 "extern void gt_%sx_%s (void *);\n",
2210 wtd->prefix, s->u.s.tag);
2212 if (s->u.s.line.file == NULL)
2214 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2215 s->u.s.tag);
2216 continue;
2219 if (s->kind == TYPE_LANG_STRUCT)
2221 type_p ss;
2222 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2223 write_func_for_structure (s, ss, NULL, wtd);
2225 else
2226 write_func_for_structure (s, s, NULL, wtd);
2229 for (s = param_structs; s; s = s->next)
2230 if (s->gc_used == GC_POINTED_TO)
2232 type_p * param = s->u.param_struct.param;
2233 type_p stru = s->u.param_struct.stru;
2235 /* Declare the marker procedure. */
2236 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2237 output_mangled_typename (header_file, s);
2238 oprintf (header_file, " (void *);\n");
2240 if (stru->u.s.line.file == NULL)
2242 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2243 s->u.s.tag);
2244 continue;
2247 if (stru->kind == TYPE_LANG_STRUCT)
2249 type_p ss;
2250 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2251 write_func_for_structure (s, ss, param, wtd);
2253 else
2254 write_func_for_structure (s, stru, param, wtd);
2258 static const struct write_types_data ggc_wtd =
2260 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2261 "GC marker procedures. "
2264 static const struct write_types_data pch_wtd =
2266 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2267 "gt_pch_note_reorder",
2268 "PCH type-walking procedures. "
2271 /* Write out the local pointer-walking routines. */
2273 /* process_field routine for local pointer-walking. */
2275 static void
2276 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2278 switch (f->kind)
2280 case TYPE_POINTER:
2281 case TYPE_STRUCT:
2282 case TYPE_UNION:
2283 case TYPE_LANG_STRUCT:
2284 case TYPE_PARAM_STRUCT:
2285 case TYPE_STRING:
2286 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2287 d->prev_val[3]);
2288 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2289 break;
2291 case TYPE_SCALAR:
2292 break;
2294 default:
2295 gcc_unreachable ();
2299 /* For S, a structure that's part of ORIG_S, and using parameters
2300 PARAM, write out a routine that:
2301 - Is of type gt_note_pointers
2302 - Calls PROCESS_FIELD on each field of S or its substructures.
2305 static void
2306 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2308 const char *fn = s->u.s.line.file;
2309 int i;
2310 struct walk_type_data d;
2312 /* This is a hack, and not the good kind either. */
2313 for (i = NUM_PARAM - 1; i >= 0; i--)
2314 if (param && param[i] && param[i]->kind == TYPE_POINTER
2315 && UNION_OR_STRUCT_P (param[i]->u.p))
2316 fn = param[i]->u.p->u.s.line.file;
2318 memset (&d, 0, sizeof (d));
2319 d.of = get_output_file_with_visibility (fn);
2321 d.process_field = write_types_local_process_field;
2322 d.opt = s->u.s.opt;
2323 d.line = &s->u.s.line;
2324 d.bitmap = s->u.s.bitmap;
2325 d.param = param;
2326 d.prev_val[0] = d.prev_val[2] = "*x";
2327 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2328 d.prev_val[3] = "x";
2329 d.val = "(*x)";
2330 d.fn_wants_lvalue = true;
2332 oprintf (d.of, "\n");
2333 oprintf (d.of, "void\n");
2334 oprintf (d.of, "gt_pch_p_");
2335 output_mangled_typename (d.of, orig_s);
2336 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2337 "\tvoid *x_p,\n"
2338 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2339 "\tATTRIBUTE_UNUSED void *cookie)\n");
2340 oprintf (d.of, "{\n");
2341 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2342 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2343 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2344 d.indent = 2;
2345 walk_type (s, &d);
2346 oprintf (d.of, "}\n");
2349 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2351 static void
2352 write_local (type_p structures, type_p param_structs)
2354 type_p s;
2356 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2357 for (s = structures; s; s = s->next)
2358 if (s->gc_used == GC_POINTED_TO
2359 || s->gc_used == GC_MAYBE_POINTED_TO)
2361 options_p opt;
2363 if (s->u.s.line.file == NULL)
2364 continue;
2366 for (opt = s->u.s.opt; opt; opt = opt->next)
2367 if (strcmp (opt->name, "ptr_alias") == 0)
2369 type_p t = (type_p) opt->info;
2370 if (t->kind == TYPE_STRUCT
2371 || t->kind == TYPE_UNION
2372 || t->kind == TYPE_LANG_STRUCT)
2374 oprintf (header_file, "#define gt_pch_p_");
2375 output_mangled_typename (header_file, s);
2376 oprintf (header_file, " gt_pch_p_");
2377 output_mangled_typename (header_file, t);
2378 oprintf (header_file, "\n");
2380 else
2381 error_at_line (&s->u.s.line,
2382 "structure alias is not a structure");
2383 break;
2385 if (opt)
2386 continue;
2388 /* Declare the marker procedure only once. */
2389 oprintf (header_file, "extern void gt_pch_p_");
2390 output_mangled_typename (header_file, s);
2391 oprintf (header_file,
2392 "\n (void *, void *, gt_pointer_operator, void *);\n");
2394 if (s->kind == TYPE_LANG_STRUCT)
2396 type_p ss;
2397 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2398 write_local_func_for_structure (s, ss, NULL);
2400 else
2401 write_local_func_for_structure (s, s, NULL);
2404 for (s = param_structs; s; s = s->next)
2405 if (s->gc_used == GC_POINTED_TO)
2407 type_p * param = s->u.param_struct.param;
2408 type_p stru = s->u.param_struct.stru;
2410 /* Declare the marker procedure. */
2411 oprintf (header_file, "extern void gt_pch_p_");
2412 output_mangled_typename (header_file, s);
2413 oprintf (header_file,
2414 "\n (void *, void *, gt_pointer_operator, void *);\n");
2416 if (stru->u.s.line.file == NULL)
2418 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2419 s->u.s.tag);
2420 continue;
2423 if (stru->kind == TYPE_LANG_STRUCT)
2425 type_p ss;
2426 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2427 write_local_func_for_structure (s, ss, param);
2429 else
2430 write_local_func_for_structure (s, stru, param);
2434 /* Write out the 'enum' definition for gt_types_enum. */
2436 static void
2437 write_enum_defn (type_p structures, type_p param_structs)
2439 type_p s;
2441 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2442 oprintf (header_file, "enum gt_types_enum {\n");
2443 for (s = structures; s; s = s->next)
2444 if (s->gc_used == GC_POINTED_TO
2445 || s->gc_used == GC_MAYBE_POINTED_TO)
2447 if (s->gc_used == GC_MAYBE_POINTED_TO
2448 && s->u.s.line.file == NULL)
2449 continue;
2451 oprintf (header_file, " gt_ggc_e_");
2452 output_mangled_typename (header_file, s);
2453 oprintf (header_file, ", \n");
2455 for (s = param_structs; s; s = s->next)
2456 if (s->gc_used == GC_POINTED_TO)
2458 oprintf (header_file, " gt_e_");
2459 output_mangled_typename (header_file, s);
2460 oprintf (header_file, ", \n");
2462 oprintf (header_file, " gt_types_enum_last\n");
2463 oprintf (header_file, "};\n");
2466 /* Might T contain any non-pointer elements? */
2468 static int
2469 contains_scalar_p (type_p t)
2471 switch (t->kind)
2473 case TYPE_STRING:
2474 case TYPE_POINTER:
2475 return 0;
2476 case TYPE_ARRAY:
2477 return contains_scalar_p (t->u.a.p);
2478 default:
2479 /* Could also check for structures that have no non-pointer
2480 fields, but there aren't enough of those to worry about. */
2481 return 1;
2485 /* Mangle FN and print it to F. */
2487 static void
2488 put_mangled_filename (outf_p f, const char *fn)
2490 const char *name = get_output_file_name (fn);
2491 for (; *name != 0; name++)
2492 if (ISALNUM (*name))
2493 oprintf (f, "%c", *name);
2494 else
2495 oprintf (f, "%c", '_');
2498 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2499 LASTNAME, and NAME are all strings to insert in various places in
2500 the resulting code. */
2502 static void
2503 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2504 const char *tname, const char *name)
2506 struct flist *fli2;
2508 for (fli2 = flp; fli2; fli2 = fli2->next)
2509 if (fli2->started_p)
2511 oprintf (fli2->f, " %s\n", lastname);
2512 oprintf (fli2->f, "};\n\n");
2515 for (fli2 = flp; fli2; fli2 = fli2->next)
2516 if (fli2->started_p)
2518 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2519 int fnum;
2521 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2522 if (bitmap & 1)
2524 oprintf (base_files[fnum],
2525 "extern const struct %s gt_%s_",
2526 tname, pfx);
2527 put_mangled_filename (base_files[fnum], fli2->name);
2528 oprintf (base_files[fnum], "[];\n");
2533 size_t fnum;
2534 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2535 oprintf (base_files [fnum],
2536 "const struct %s * const %s[] = {\n",
2537 tname, name);
2541 for (fli2 = flp; fli2; fli2 = fli2->next)
2542 if (fli2->started_p)
2544 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2545 int fnum;
2547 fli2->started_p = 0;
2549 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2550 if (bitmap & 1)
2552 oprintf (base_files[fnum], " gt_%s_", pfx);
2553 put_mangled_filename (base_files[fnum], fli2->name);
2554 oprintf (base_files[fnum], ",\n");
2559 size_t fnum;
2560 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2562 oprintf (base_files[fnum], " NULL\n");
2563 oprintf (base_files[fnum], "};\n");
2568 /* Write out to F the table entry and any marker routines needed to
2569 mark NAME as TYPE. The original variable is V, at LINE.
2570 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2571 is nonzero iff we are building the root table for hash table caches. */
2573 static void
2574 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2575 struct fileloc *line, const char *if_marked)
2577 switch (type->kind)
2579 case TYPE_STRUCT:
2581 pair_p fld;
2582 for (fld = type->u.s.fields; fld; fld = fld->next)
2584 int skip_p = 0;
2585 const char *desc = NULL;
2586 options_p o;
2588 for (o = fld->opt; o; o = o->next)
2589 if (strcmp (o->name, "skip") == 0)
2590 skip_p = 1;
2591 else if (strcmp (o->name, "desc") == 0)
2592 desc = o->info;
2593 else
2594 error_at_line (line,
2595 "field `%s' of global `%s' has unknown option `%s'",
2596 fld->name, name, o->name);
2598 if (skip_p)
2599 continue;
2600 else if (desc && fld->type->kind == TYPE_UNION)
2602 pair_p validf = NULL;
2603 pair_p ufld;
2605 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2607 const char *tag = NULL;
2608 options_p oo;
2610 for (oo = ufld->opt; oo; oo = oo->next)
2611 if (strcmp (oo->name, "tag") == 0)
2612 tag = oo->info;
2613 if (tag == NULL || strcmp (tag, desc) != 0)
2614 continue;
2615 if (validf != NULL)
2616 error_at_line (line,
2617 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2618 name, fld->name, validf->name,
2619 name, fld->name, ufld->name,
2620 tag);
2621 validf = ufld;
2623 if (validf != NULL)
2625 char *newname;
2626 newname = xasprintf ("%s.%s.%s",
2627 name, fld->name, validf->name);
2628 write_root (f, v, validf->type, newname, 0, line,
2629 if_marked);
2630 free (newname);
2633 else if (desc)
2634 error_at_line (line,
2635 "global `%s.%s' has `desc' option but is not union",
2636 name, fld->name);
2637 else
2639 char *newname;
2640 newname = xasprintf ("%s.%s", name, fld->name);
2641 write_root (f, v, fld->type, newname, 0, line, if_marked);
2642 free (newname);
2646 break;
2648 case TYPE_ARRAY:
2650 char *newname;
2651 newname = xasprintf ("%s[0]", name);
2652 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2653 free (newname);
2655 break;
2657 case TYPE_POINTER:
2659 type_p ap, tp;
2661 oprintf (f, " {\n");
2662 oprintf (f, " &%s,\n", name);
2663 oprintf (f, " 1");
2665 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2666 if (ap->u.a.len[0])
2667 oprintf (f, " * (%s)", ap->u.a.len);
2668 else if (ap == v->type)
2669 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2670 oprintf (f, ",\n");
2671 oprintf (f, " sizeof (%s", v->name);
2672 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2673 oprintf (f, "[0]");
2674 oprintf (f, "),\n");
2676 tp = type->u.p;
2678 if (! has_length && UNION_OR_STRUCT_P (tp))
2680 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2681 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2683 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2685 oprintf (f, " &gt_ggc_m_");
2686 output_mangled_typename (f, tp);
2687 oprintf (f, ",\n &gt_pch_n_");
2688 output_mangled_typename (f, tp);
2690 else if (has_length
2691 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2693 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2694 oprintf (f, " &gt_pch_na_%s", name);
2696 else
2698 error_at_line (line,
2699 "global `%s' is pointer to unimplemented type",
2700 name);
2702 if (if_marked)
2703 oprintf (f, ",\n &%s", if_marked);
2704 oprintf (f, "\n },\n");
2706 break;
2708 case TYPE_STRING:
2710 oprintf (f, " {\n");
2711 oprintf (f, " &%s,\n", name);
2712 oprintf (f, " 1, \n");
2713 oprintf (f, " sizeof (%s),\n", v->name);
2714 oprintf (f, " &gt_ggc_m_S,\n");
2715 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2716 oprintf (f, " },\n");
2718 break;
2720 case TYPE_SCALAR:
2721 break;
2723 default:
2724 error_at_line (line,
2725 "global `%s' is unimplemented type",
2726 name);
2730 /* This generates a routine to walk an array. */
2732 static void
2733 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2735 struct walk_type_data d;
2736 char *prevval3;
2738 memset (&d, 0, sizeof (d));
2739 d.of = f;
2740 d.cookie = wtd;
2741 d.indent = 2;
2742 d.line = &v->line;
2743 d.opt = v->opt;
2744 d.bitmap = get_base_file_bitmap (v->line.file);
2745 d.param = NULL;
2747 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2749 if (wtd->param_prefix)
2751 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2752 oprintf (f,
2753 " (void *, void *, gt_pointer_operator, void *);\n");
2754 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2755 wtd->param_prefix, v->name);
2756 oprintf (d.of,
2757 " ATTRIBUTE_UNUSED void *x_p,\n"
2758 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2759 " ATTRIBUTE_UNUSED void * cookie)\n");
2760 oprintf (d.of, "{\n");
2761 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2762 d.process_field = write_types_local_process_field;
2763 walk_type (v->type, &d);
2764 oprintf (f, "}\n\n");
2767 d.opt = v->opt;
2768 oprintf (f, "static void gt_%sa_%s (void *);\n",
2769 wtd->prefix, v->name);
2770 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2771 wtd->prefix, v->name);
2772 oprintf (f, "{\n");
2773 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2774 d.process_field = write_types_process_field;
2775 walk_type (v->type, &d);
2776 free (prevval3);
2777 oprintf (f, "}\n\n");
2780 /* Output a table describing the locations and types of VARIABLES. */
2782 static void
2783 write_roots (pair_p variables)
2785 pair_p v;
2786 struct flist *flp = NULL;
2788 for (v = variables; v; v = v->next)
2790 outf_p f = get_output_file_with_visibility (v->line.file);
2791 struct flist *fli;
2792 const char *length = NULL;
2793 int deletable_p = 0;
2794 options_p o;
2796 for (o = v->opt; o; o = o->next)
2797 if (strcmp (o->name, "length") == 0)
2798 length = o->info;
2799 else if (strcmp (o->name, "deletable") == 0)
2800 deletable_p = 1;
2801 else if (strcmp (o->name, "param_is") == 0)
2803 else if (strncmp (o->name, "param", 5) == 0
2804 && ISDIGIT (o->name[5])
2805 && strcmp (o->name + 6, "_is") == 0)
2807 else if (strcmp (o->name, "if_marked") == 0)
2809 else
2810 error_at_line (&v->line,
2811 "global `%s' has unknown option `%s'",
2812 v->name, o->name);
2814 for (fli = flp; fli; fli = fli->next)
2815 if (fli->f == f)
2816 break;
2817 if (fli == NULL)
2819 fli = XNEW (struct flist);
2820 fli->f = f;
2821 fli->next = flp;
2822 fli->started_p = 0;
2823 fli->name = v->line.file;
2824 flp = fli;
2826 oprintf (f, "\n/* GC roots. */\n\n");
2829 if (! deletable_p
2830 && length
2831 && v->type->kind == TYPE_POINTER
2832 && (v->type->u.p->kind == TYPE_POINTER
2833 || v->type->u.p->kind == TYPE_STRUCT))
2835 write_array (f, v, &ggc_wtd);
2836 write_array (f, v, &pch_wtd);
2840 for (v = variables; v; v = v->next)
2842 outf_p f = get_output_file_with_visibility (v->line.file);
2843 struct flist *fli;
2844 int skip_p = 0;
2845 int length_p = 0;
2846 options_p o;
2848 for (o = v->opt; o; o = o->next)
2849 if (strcmp (o->name, "length") == 0)
2850 length_p = 1;
2851 else if (strcmp (o->name, "deletable") == 0
2852 || strcmp (o->name, "if_marked") == 0)
2853 skip_p = 1;
2855 if (skip_p)
2856 continue;
2858 for (fli = flp; fli; fli = fli->next)
2859 if (fli->f == f)
2860 break;
2861 if (! fli->started_p)
2863 fli->started_p = 1;
2865 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2866 put_mangled_filename (f, v->line.file);
2867 oprintf (f, "[] = {\n");
2870 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2873 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2874 "gt_ggc_rtab");
2876 for (v = variables; v; v = v->next)
2878 outf_p f = get_output_file_with_visibility (v->line.file);
2879 struct flist *fli;
2880 int skip_p = 1;
2881 options_p o;
2883 for (o = v->opt; o; o = o->next)
2884 if (strcmp (o->name, "deletable") == 0)
2885 skip_p = 0;
2886 else if (strcmp (o->name, "if_marked") == 0)
2887 skip_p = 1;
2889 if (skip_p)
2890 continue;
2892 for (fli = flp; fli; fli = fli->next)
2893 if (fli->f == f)
2894 break;
2895 if (! fli->started_p)
2897 fli->started_p = 1;
2899 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2900 put_mangled_filename (f, v->line.file);
2901 oprintf (f, "[] = {\n");
2904 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2905 v->name, v->name);
2908 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2909 "gt_ggc_deletable_rtab");
2911 for (v = variables; v; v = v->next)
2913 outf_p f = get_output_file_with_visibility (v->line.file);
2914 struct flist *fli;
2915 const char *if_marked = NULL;
2916 int length_p = 0;
2917 options_p o;
2919 for (o = v->opt; o; o = o->next)
2920 if (strcmp (o->name, "length") == 0)
2921 length_p = 1;
2922 else if (strcmp (o->name, "if_marked") == 0)
2923 if_marked = o->info;
2925 if (if_marked == NULL)
2926 continue;
2928 if (v->type->kind != TYPE_POINTER
2929 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2930 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2932 error_at_line (&v->line, "if_marked option used but not hash table");
2933 continue;
2936 for (fli = flp; fli; fli = fli->next)
2937 if (fli->f == f)
2938 break;
2939 if (! fli->started_p)
2941 fli->started_p = 1;
2943 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2944 put_mangled_filename (f, v->line.file);
2945 oprintf (f, "[] = {\n");
2948 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2949 v->name, length_p, &v->line, if_marked);
2952 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2953 "gt_ggc_cache_rtab");
2955 for (v = variables; v; v = v->next)
2957 outf_p f = get_output_file_with_visibility (v->line.file);
2958 struct flist *fli;
2959 int length_p = 0;
2960 int if_marked_p = 0;
2961 options_p o;
2963 for (o = v->opt; o; o = o->next)
2964 if (strcmp (o->name, "length") == 0)
2965 length_p = 1;
2966 else if (strcmp (o->name, "if_marked") == 0)
2967 if_marked_p = 1;
2969 if (! if_marked_p)
2970 continue;
2972 for (fli = flp; fli; fli = fli->next)
2973 if (fli->f == f)
2974 break;
2975 if (! fli->started_p)
2977 fli->started_p = 1;
2979 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2980 put_mangled_filename (f, v->line.file);
2981 oprintf (f, "[] = {\n");
2984 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2987 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2988 "gt_pch_cache_rtab");
2990 for (v = variables; v; v = v->next)
2992 outf_p f = get_output_file_with_visibility (v->line.file);
2993 struct flist *fli;
2994 int skip_p = 0;
2995 options_p o;
2997 for (o = v->opt; o; o = o->next)
2998 if (strcmp (o->name, "deletable") == 0
2999 || strcmp (o->name, "if_marked") == 0)
3000 skip_p = 1;
3002 if (skip_p)
3003 continue;
3005 if (! contains_scalar_p (v->type))
3006 continue;
3008 for (fli = flp; fli; fli = fli->next)
3009 if (fli->f == f)
3010 break;
3011 if (! fli->started_p)
3013 fli->started_p = 1;
3015 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3016 put_mangled_filename (f, v->line.file);
3017 oprintf (f, "[] = {\n");
3020 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3021 v->name, v->name);
3024 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3025 "gt_pch_scalar_rtab");
3029 extern int main (int argc, char **argv);
3031 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
3033 unsigned i;
3034 static struct fileloc pos = { __FILE__, __LINE__ };
3035 unsigned j;
3037 gen_rtx_next ();
3039 srcdir_len = strlen (srcdir);
3041 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3042 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3043 do_scalar_typedef ("double_int", &pos);
3044 do_scalar_typedef ("uint8", &pos);
3045 do_scalar_typedef ("jword", &pos);
3046 do_scalar_typedef ("JCF_u2", &pos);
3047 #ifdef USE_MAPPED_LOCATION
3048 do_scalar_typedef ("location_t", &pos);
3049 do_scalar_typedef ("source_locus", &pos);
3050 #endif
3051 do_scalar_typedef ("void", &pos);
3053 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3055 do_typedef ("HARD_REG_SET", create_array (
3056 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3057 "2"), &pos);
3059 for (i = 0; i < NUM_GT_FILES; i++)
3061 int dupflag = 0;
3062 /* Omit if already seen. */
3063 for (j = 0; j < i; j++)
3065 if (!strcmp (all_files[i], all_files[j]))
3067 dupflag = 1;
3068 break;
3071 if (!dupflag)
3072 parse_file (all_files[i]);
3073 #ifndef USE_MAPPED_LOCATION
3074 /* temporary kludge - gengtype doesn't handle conditionals.
3075 Manually add source_locus *after* we've processed input.h. */
3076 if (i == 0)
3077 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3078 #endif
3081 if (hit_error != 0)
3082 exit (1);
3084 set_gc_used (variables);
3086 open_base_files ();
3087 write_enum_defn (structures, param_structs);
3088 write_types (structures, param_structs, &ggc_wtd);
3089 write_types (structures, param_structs, &pch_wtd);
3090 write_local (structures, param_structs);
3091 write_roots (variables);
3092 write_rtx_next ();
3093 close_output_files ();
3095 return (hit_error != 0);