Mark as release
[official-gcc.git] / gcc / gengtype.c
blob1e5f0f1e233670f6a14a10a0efb98a2b1684ee18
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 3, 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 COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "bconfig.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "gengtype.h"
25 #include "gtyp-gen.h"
26 #include "errors.h"
28 /* Nonzero iff an error has occurred. */
29 static int hit_error = 0;
31 static void gen_rtx_next (void);
32 static void write_rtx_next (void);
33 static void open_base_files (void);
34 static void close_output_files (void);
36 /* Report an error at POS, printing MSG. */
38 void
39 error_at_line (struct fileloc *pos, const char *msg, ...)
41 va_list ap;
43 va_start (ap, 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_end (ap);
53 /* vasprintf, but produces fatal message on out-of-memory. */
54 int
55 xvasprintf (char **result, const char *format, va_list args)
57 int ret = vasprintf (result, format, args);
58 if (*result == NULL || ret < 0)
60 fputs ("gengtype: out of memory", stderr);
61 xexit (1);
63 return ret;
66 /* Wrapper for xvasprintf. */
67 char *
68 xasprintf (const char *format, ...)
70 char *result;
71 va_list ap;
73 va_start (ap, format);
74 xvasprintf (&result, format, ap);
75 va_end (ap);
76 return result;
79 /* The one and only TYPE_STRING. */
81 struct type string_type = {
82 TYPE_STRING, NULL, NULL, GC_USED, {0}
85 /* Lists of various things. */
87 static pair_p typedefs;
88 static type_p structures;
89 static type_p param_structs;
90 static pair_p variables;
92 static void do_scalar_typedef (const char *, struct fileloc *);
93 static type_p find_param_structure
94 (type_p t, type_p param[NUM_PARAM]);
95 static type_p adjust_field_tree_exp (type_p t, options_p opt);
96 static type_p adjust_field_rtx_def (type_p t, options_p opt);
98 /* Define S as a typedef to T at POS. */
100 void
101 do_typedef (const char *s, type_p t, struct fileloc *pos)
103 pair_p p;
105 for (p = typedefs; p != NULL; p = p->next)
106 if (strcmp (p->name, s) == 0)
108 if (p->type != t)
110 error_at_line (pos, "type `%s' previously defined", s);
111 error_at_line (&p->line, "previously defined here");
113 return;
116 p = XNEW (struct pair);
117 p->next = typedefs;
118 p->name = s;
119 p->type = t;
120 p->line = *pos;
121 typedefs = p;
124 /* Define S as a typename of a scalar. */
126 static void
127 do_scalar_typedef (const char *s, struct fileloc *pos)
129 do_typedef (s, create_scalar_type (s, strlen (s)), pos);
132 /* Return the type previously defined for S. Use POS to report errors. */
134 type_p
135 resolve_typedef (const char *s, struct fileloc *pos)
137 pair_p p;
138 for (p = typedefs; p != NULL; p = p->next)
139 if (strcmp (p->name, s) == 0)
140 return p->type;
141 error_at_line (pos, "unidentified type `%s'", s);
142 return create_scalar_type ("char", 4);
145 /* Create and return a new structure with tag NAME (or a union iff
146 ISUNION is nonzero), at POS with fields FIELDS and options O. */
148 type_p
149 new_structure (const char *name, int isunion, struct fileloc *pos,
150 pair_p fields, options_p o)
152 type_p si;
153 type_p s = NULL;
154 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
156 for (si = structures; si != NULL; si = si->next)
157 if (strcmp (name, si->u.s.tag) == 0
158 && UNION_P (si) == isunion)
160 type_p ls = NULL;
161 if (si->kind == TYPE_LANG_STRUCT)
163 ls = si;
165 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
166 if (si->u.s.bitmap == bitmap)
167 s = si;
169 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
171 ls = si;
172 si = XCNEW (struct type);
173 memcpy (si, ls, sizeof (struct type));
174 ls->kind = TYPE_LANG_STRUCT;
175 ls->u.s.lang_struct = si;
176 ls->u.s.fields = NULL;
177 si->next = NULL;
178 si->pointer_to = NULL;
179 si->u.s.lang_struct = ls;
181 else
182 s = si;
184 if (ls != NULL && s == NULL)
186 s = XCNEW (struct type);
187 s->next = ls->u.s.lang_struct;
188 ls->u.s.lang_struct = s;
189 s->u.s.lang_struct = ls;
191 break;
194 if (s == NULL)
196 s = XCNEW (struct type);
197 s->next = structures;
198 structures = s;
201 if (s->u.s.line.file != NULL
202 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
204 error_at_line (pos, "duplicate structure definition");
205 error_at_line (&s->u.s.line, "previous definition here");
208 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
209 s->u.s.tag = name;
210 s->u.s.line = *pos;
211 s->u.s.fields = fields;
212 s->u.s.opt = o;
213 s->u.s.bitmap = bitmap;
214 if (s->u.s.lang_struct)
215 s->u.s.lang_struct->u.s.bitmap |= bitmap;
217 return s;
220 /* Return the previously-defined structure with tag NAME (or a union
221 iff ISUNION is nonzero), or a new empty structure or union if none
222 was defined previously. */
224 type_p
225 find_structure (const char *name, int isunion)
227 type_p s;
229 for (s = structures; s != NULL; s = s->next)
230 if (strcmp (name, s->u.s.tag) == 0
231 && UNION_P (s) == isunion)
232 return s;
234 s = XCNEW (struct type);
235 s->next = structures;
236 structures = s;
237 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
238 s->u.s.tag = name;
239 structures = s;
240 return s;
243 /* Return the previously-defined parameterized structure for structure
244 T and parameters PARAM, or a new parameterized empty structure or
245 union if none was defined previously. */
247 static type_p
248 find_param_structure (type_p t, type_p param[NUM_PARAM])
250 type_p res;
252 for (res = param_structs; res; res = res->next)
253 if (res->u.param_struct.stru == t
254 && memcmp (res->u.param_struct.param, param,
255 sizeof (type_p) * NUM_PARAM) == 0)
256 break;
257 if (res == NULL)
259 res = XCNEW (struct type);
260 res->kind = TYPE_PARAM_STRUCT;
261 res->next = param_structs;
262 param_structs = res;
263 res->u.param_struct.stru = t;
264 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
266 return res;
269 /* Return a scalar type with name NAME. */
271 type_p
272 create_scalar_type (const char *name, size_t name_len)
274 type_p r = XCNEW (struct type);
275 r->kind = TYPE_SCALAR;
276 r->u.sc = (char *) xmemdup (name, name_len, name_len + 1);
277 return r;
280 /* Return a pointer to T. */
282 type_p
283 create_pointer (type_p t)
285 if (! t->pointer_to)
287 type_p r = XCNEW (struct type);
288 r->kind = TYPE_POINTER;
289 r->u.p = t;
290 t->pointer_to = r;
292 return t->pointer_to;
295 /* Return an array of length LEN. */
297 type_p
298 create_array (type_p t, const char *len)
300 type_p v;
302 v = XCNEW (struct type);
303 v->kind = TYPE_ARRAY;
304 v->u.a.p = t;
305 v->u.a.len = len;
306 return v;
309 /* Return an options structure with name NAME and info INFO. NEXT is the
310 next option in the chain. */
312 options_p
313 create_option (options_p next, const char *name, const void *info)
315 options_p o = XNEW (struct options);
316 o->next = next;
317 o->name = name;
318 o->info = (const char*) info;
319 return o;
322 /* Add a variable named S of type T with options O defined at POS,
323 to `variables'. */
325 void
326 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
328 pair_p n;
329 n = XNEW (struct pair);
330 n->name = s;
331 n->type = t;
332 n->line = *pos;
333 n->opt = o;
334 n->next = variables;
335 variables = n;
338 /* Create a fake field with the given type and name. NEXT is the next
339 field in the chain. */
341 static pair_p
342 create_field (pair_p next, type_p type, const char *name)
344 pair_p field;
346 field = XNEW (struct pair);
347 field->next = next;
348 field->type = type;
349 field->name = name;
350 field->opt = NULL;
351 field->line.file = __FILE__;
352 field->line.line = __LINE__;
353 return field;
356 /* Like create_field, but the field is only valid when condition COND
357 is true. */
359 static pair_p
360 create_optional_field (pair_p next, type_p type, const char *name,
361 const char *cond)
363 static int id = 1;
364 pair_p union_fields, field;
365 type_p union_type;
367 /* Create a fake union type with a single nameless field of type TYPE.
368 The field has a tag of "1". This allows us to make the presence
369 of a field of type TYPE depend on some boolean "desc" being true. */
370 union_fields = create_field (NULL, type, "");
371 union_fields->opt = create_option (union_fields->opt, "dot", "");
372 union_fields->opt = create_option (union_fields->opt, "tag", "1");
373 union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
374 &lexer_line, union_fields, NULL);
376 /* Create the field and give it the new fake union type. Add a "desc"
377 tag that specifies the condition under which the field is valid. */
378 field = create_field (next, union_type, name);
379 field->opt = create_option (field->opt, "desc", cond);
380 return field;
383 /* We don't care how long a CONST_DOUBLE is. */
384 #define CONST_DOUBLE_FORMAT "ww"
385 /* We don't want to see codes that are only for generator files. */
386 #undef GENERATOR_FILE
388 enum rtx_code {
389 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
390 #include "rtl.def"
391 #undef DEF_RTL_EXPR
392 NUM_RTX_CODE
395 static const char * const rtx_name[NUM_RTX_CODE] = {
396 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
397 #include "rtl.def"
398 #undef DEF_RTL_EXPR
401 static const char * const rtx_format[NUM_RTX_CODE] = {
402 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
403 #include "rtl.def"
404 #undef DEF_RTL_EXPR
407 static int rtx_next_new[NUM_RTX_CODE];
409 /* We also need codes and names for insn notes (not register notes).
410 Note that we do *not* bias the note values here. */
411 enum insn_note {
412 #define DEF_INSN_NOTE(NAME) NAME,
413 #include "insn-notes.def"
414 #undef DEF_INSN_NOTE
416 NOTE_INSN_MAX
419 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
420 default field for line number notes. */
421 static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
422 #define DEF_INSN_NOTE(NAME) #NAME,
423 #include "insn-notes.def"
424 #undef DEF_INSN_NOTE
427 #undef CONST_DOUBLE_FORMAT
428 #define GENERATOR_FILE
430 /* Generate the contents of the rtx_next array. This really doesn't belong
431 in gengtype at all, but it's needed for adjust_field_rtx_def. */
433 static void
434 gen_rtx_next (void)
436 int i;
437 for (i = 0; i < NUM_RTX_CODE; i++)
439 int k;
441 rtx_next_new[i] = -1;
442 if (strncmp (rtx_format[i], "iuu", 3) == 0)
443 rtx_next_new[i] = 2;
444 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
445 rtx_next_new[i] = 1;
446 else
447 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
448 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
449 rtx_next_new[i] = k;
453 /* Write out the contents of the rtx_next array. */
454 static void
455 write_rtx_next (void)
457 outf_p f = get_output_file_with_visibility (NULL);
458 int i;
460 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
461 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
462 for (i = 0; i < NUM_RTX_CODE; i++)
463 if (rtx_next_new[i] == -1)
464 oprintf (f, " 0,\n");
465 else
466 oprintf (f,
467 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
468 rtx_next_new[i]);
469 oprintf (f, "};\n");
472 /* Handle `special("rtx_def")'. This is a special case for field
473 `fld' of struct rtx_def, which is an array of unions whose values
474 are based in a complex way on the type of RTL. */
476 static type_p
477 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
479 pair_p flds = NULL;
480 options_p nodot;
481 int i;
482 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
483 type_p bitmap_tp, basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
485 if (t->kind != TYPE_UNION)
487 error_at_line (&lexer_line,
488 "special `rtx_def' must be applied to a union");
489 return &string_type;
492 nodot = create_option (NULL, "dot", "");
494 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
495 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
496 tree_tp = create_pointer (find_structure ("tree_node", 1));
497 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
498 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
499 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
500 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
501 constant_tp = create_pointer (find_structure ("constant_descriptor_rtx", 0));
502 scalar_tp = create_scalar_type ("rtunion scalar", 14);
505 pair_p note_flds = NULL;
506 int c;
508 for (c = 0; c <= NOTE_INSN_MAX; c++)
510 switch (c)
512 case NOTE_INSN_MAX:
513 note_flds = create_field (note_flds, &string_type, "rt_str");
514 break;
516 case NOTE_INSN_BLOCK_BEG:
517 case NOTE_INSN_BLOCK_END:
518 note_flds = create_field (note_flds, tree_tp, "rt_tree");
519 break;
521 case NOTE_INSN_EXPECTED_VALUE:
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 process_gc_options (options_p, enum gc_used_enum,
873 int *, int *, int *, type_p *);
874 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
875 static void set_gc_used (pair_p);
877 /* Handle OPT for set_gc_used_type. */
879 static void
880 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
881 int *pass_param, int *length, type_p *nested_ptr)
883 options_p o;
884 for (o = opt; o; o = o->next)
885 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
886 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
887 else if (strcmp (o->name, "maybe_undef") == 0)
888 *maybe_undef = 1;
889 else if (strcmp (o->name, "use_params") == 0)
890 *pass_param = 1;
891 else if (strcmp (o->name, "length") == 0)
892 *length = 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,
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 type_p nested_ptr = NULL;
925 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
926 &length, &nested_ptr);
928 if (nested_ptr && f->type->kind == TYPE_POINTER)
929 set_gc_used_type (nested_ptr, GC_POINTED_TO,
930 pass_param ? param : NULL);
931 else if (length && f->type->kind == TYPE_POINTER)
932 set_gc_used_type (f->type->u.p, GC_USED, NULL);
933 else if (maybe_undef && f->type->kind == TYPE_POINTER)
934 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
935 else if (pass_param && f->type->kind == TYPE_POINTER && param)
936 set_gc_used_type (find_param_structure (f->type->u.p, param),
937 GC_POINTED_TO, NULL);
938 else
939 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
941 break;
944 case TYPE_POINTER:
945 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
946 break;
948 case TYPE_ARRAY:
949 set_gc_used_type (t->u.a.p, GC_USED, param);
950 break;
952 case TYPE_LANG_STRUCT:
953 for (t = t->u.s.lang_struct; t; t = t->next)
954 set_gc_used_type (t, level, param);
955 break;
957 case TYPE_PARAM_STRUCT:
959 int i;
960 for (i = 0; i < NUM_PARAM; i++)
961 if (t->u.param_struct.param[i] != 0)
962 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
964 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
965 level = GC_POINTED_TO;
966 else
967 level = GC_USED;
968 t->u.param_struct.stru->gc_used = GC_UNUSED;
969 set_gc_used_type (t->u.param_struct.stru, level,
970 t->u.param_struct.param);
971 break;
973 default:
974 break;
978 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
980 static void
981 set_gc_used (pair_p variables)
983 pair_p p;
984 for (p = variables; p; p = p->next)
985 set_gc_used_type (p->type, GC_USED, NULL);
988 /* File mapping routines. For each input file, there is one output .c file
989 (but some output files have many input files), and there is one .h file
990 for the whole build. */
992 /* The list of output files. */
993 static outf_p output_files;
995 /* The output header file that is included into pretty much every
996 source file. */
997 static outf_p header_file;
999 /* Number of files specified in gtfiles. */
1000 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1002 /* Number of files in the language files array. */
1003 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1005 /* Length of srcdir name. */
1006 static int srcdir_len = 0;
1008 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1009 outf_p base_files[NUM_BASE_FILES];
1011 static outf_p create_file (const char *, const char *);
1012 static const char * get_file_basename (const char *);
1014 /* Create and return an outf_p for a new file for NAME, to be called
1015 ONAME. */
1017 static outf_p
1018 create_file (const char *name, const char *oname)
1020 static const char *const hdr[] = {
1021 " Copyright (C) 2004, 2007 Free Software Foundation, Inc.\n",
1022 "\n",
1023 "This file is part of GCC.\n",
1024 "\n",
1025 "GCC is free software; you can redistribute it and/or modify it under\n",
1026 "the terms of the GNU General Public License as published by the Free\n",
1027 "Software Foundation; either version 3, or (at your option) any later\n",
1028 "version.\n",
1029 "\n",
1030 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1031 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1032 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1033 "for more details.\n",
1034 "\n",
1035 "You should have received a copy of the GNU General Public License\n",
1036 "along with GCC; see the file COPYING3. If not see\n",
1037 "<http://www.gnu.org/licenses/>. */\n",
1038 "\n",
1039 "/* This file is machine generated. Do not edit. */\n"
1041 outf_p f;
1042 size_t i;
1044 f = XCNEW (struct outf);
1045 f->next = output_files;
1046 f->name = oname;
1047 output_files = f;
1049 oprintf (f, "/* Type information for %s.\n", name);
1050 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1051 oprintf (f, "%s", hdr[i]);
1052 return f;
1055 /* Print, like fprintf, to O. */
1056 void
1057 oprintf (outf_p o, const char *format, ...)
1059 char *s;
1060 size_t slength;
1061 va_list ap;
1063 va_start (ap, format);
1064 slength = xvasprintf (&s, format, ap);
1066 if (o->bufused + slength > o->buflength)
1068 size_t new_len = o->buflength;
1069 if (new_len == 0)
1070 new_len = 1024;
1071 do {
1072 new_len *= 2;
1073 } while (o->bufused + slength >= new_len);
1074 o->buf = XRESIZEVEC (char, o->buf, new_len);
1075 o->buflength = new_len;
1077 memcpy (o->buf + o->bufused, s, slength);
1078 o->bufused += slength;
1079 free (s);
1080 va_end (ap);
1083 /* Open the global header file and the language-specific header files. */
1085 static void
1086 open_base_files (void)
1088 size_t i;
1090 header_file = create_file ("GCC", "gtype-desc.h");
1092 for (i = 0; i < NUM_BASE_FILES; i++)
1093 base_files[i] = create_file (lang_dir_names[i],
1094 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1096 /* gtype-desc.c is a little special, so we create it here. */
1098 /* The order of files here matters very much. */
1099 static const char *const ifiles [] = {
1100 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1101 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1102 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1103 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1104 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1105 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1106 "except.h", "output.h", NULL
1108 const char *const *ifp;
1109 outf_p gtype_desc_c;
1111 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1112 for (ifp = ifiles; *ifp; ifp++)
1113 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1117 /* Determine the pathname to F relative to $(srcdir). */
1119 static const char *
1120 get_file_basename (const char *f)
1122 const char *basename;
1123 unsigned i;
1125 basename = strrchr (f, '/');
1127 if (!basename)
1128 return f;
1130 basename++;
1132 for (i = 1; i < NUM_BASE_FILES; i++)
1134 const char * s1;
1135 const char * s2;
1136 int l1;
1137 int l2;
1138 s1 = basename - strlen (lang_dir_names [i]) - 1;
1139 s2 = lang_dir_names [i];
1140 l1 = strlen (s1);
1141 l2 = strlen (s2);
1142 if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1144 basename -= l2 + 1;
1145 if ((basename - f - 1) != srcdir_len)
1146 fatal ("filename `%s' should be preceded by $srcdir", f);
1147 break;
1151 return basename;
1154 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1155 INPUT_FILE is used by <lang>.
1157 This function should be written to assume that a file _is_ used
1158 if the situation is unclear. If it wrongly assumes a file _is_ used,
1159 a linker error will result. If it wrongly assumes a file _is not_ used,
1160 some GC roots may be missed, which is a much harder-to-debug problem. */
1162 unsigned
1163 get_base_file_bitmap (const char *input_file)
1165 const char *basename = get_file_basename (input_file);
1166 const char *slashpos = strchr (basename, '/');
1167 unsigned j;
1168 unsigned k;
1169 unsigned bitmap;
1171 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1172 it belongs to the corresponding language. The file may belong to other
1173 languages as well (which is checked for below). */
1175 if (slashpos)
1177 size_t i;
1178 for (i = 1; i < NUM_BASE_FILES; i++)
1179 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1180 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1182 /* It's in a language directory, set that language. */
1183 bitmap = 1 << i;
1187 /* If it's in any config-lang.in, then set for the languages
1188 specified. */
1190 bitmap = 0;
1192 for (j = 0; j < NUM_LANG_FILES; j++)
1194 if (!strcmp(input_file, lang_files[j]))
1196 for (k = 0; k < NUM_BASE_FILES; k++)
1198 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1199 bitmap |= (1 << k);
1204 /* Otherwise, set all languages. */
1205 if (!bitmap)
1206 bitmap = (1 << NUM_BASE_FILES) - 1;
1208 return bitmap;
1211 /* An output file, suitable for definitions, that can see declarations
1212 made in INPUT_FILE and is linked into every language that uses
1213 INPUT_FILE. */
1215 outf_p
1216 get_output_file_with_visibility (const char *input_file)
1218 outf_p r;
1219 size_t len;
1220 const char *basename;
1221 const char *for_name;
1222 const char *output_name;
1224 /* This can happen when we need a file with visibility on a
1225 structure that we've never seen. We have to just hope that it's
1226 globally visible. */
1227 if (input_file == NULL)
1228 input_file = "system.h";
1230 /* Determine the output file name. */
1231 basename = get_file_basename (input_file);
1233 len = strlen (basename);
1234 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1235 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1236 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1238 char *s;
1240 output_name = s = xasprintf ("gt-%s", basename);
1241 for (; *s != '.'; s++)
1242 if (! ISALNUM (*s) && *s != '-')
1243 *s = '-';
1244 memcpy (s, ".h", sizeof (".h"));
1245 for_name = basename;
1247 /* Some headers get used by more than one front-end; hence, it
1248 would be inappropriate to spew them out to a single gtype-<lang>.h
1249 (and gengtype doesn't know how to direct spewage into multiple
1250 gtype-<lang>.h headers at this time). Instead, we pair up these
1251 headers with source files (and their special purpose gt-*.h headers). */
1252 else if (strcmp (basename, "c-common.h") == 0)
1253 output_name = "gt-c-common.h", for_name = "c-common.c";
1254 else if (strcmp (basename, "c-tree.h") == 0)
1255 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1256 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1257 && strcmp (basename + 3, "cp-tree.h") == 0)
1258 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1259 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1260 && strcmp (basename + 3, "decl.h") == 0)
1261 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1262 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1263 && strcmp (basename + 3, "name-lookup.h") == 0)
1264 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1265 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1266 && strcmp (basename + 5, "objc-act.h") == 0)
1267 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1268 else
1270 size_t i;
1272 for (i = 0; i < NUM_BASE_FILES; i++)
1273 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1274 && basename[strlen(lang_dir_names[i])] == '/')
1275 return base_files[i];
1277 output_name = "gtype-desc.c";
1278 for_name = NULL;
1281 /* Look through to see if we've ever seen this output filename before. */
1282 for (r = output_files; r; r = r->next)
1283 if (strcmp (r->name, output_name) == 0)
1284 return r;
1286 /* If not, create it. */
1287 r = create_file (for_name, output_name);
1289 return r;
1292 /* The name of an output file, suitable for definitions, that can see
1293 declarations made in INPUT_FILE and is linked into every language
1294 that uses INPUT_FILE. */
1296 const char *
1297 get_output_file_name (const char *input_file)
1299 return get_output_file_with_visibility (input_file)->name;
1302 /* Copy the output to its final destination,
1303 but don't unnecessarily change modification times. */
1305 static void
1306 close_output_files (void)
1308 outf_p of;
1310 for (of = output_files; of; of = of->next)
1312 FILE * newfile;
1314 newfile = fopen (of->name, "r");
1315 if (newfile != NULL )
1317 int no_write_p;
1318 size_t i;
1320 for (i = 0; i < of->bufused; i++)
1322 int ch;
1323 ch = fgetc (newfile);
1324 if (ch == EOF || ch != (unsigned char) of->buf[i])
1325 break;
1327 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1328 fclose (newfile);
1330 if (no_write_p)
1331 continue;
1334 newfile = fopen (of->name, "w");
1335 if (newfile == NULL)
1337 perror ("opening output file");
1338 exit (1);
1340 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1342 perror ("writing output file");
1343 exit (1);
1345 if (fclose (newfile) != 0)
1347 perror ("closing output file");
1348 exit (1);
1353 struct flist {
1354 struct flist *next;
1355 int started_p;
1356 const char *name;
1357 outf_p f;
1360 struct walk_type_data;
1362 /* For scalars and strings, given the item in 'val'.
1363 For structures, given a pointer to the item in 'val'.
1364 For misc. pointers, given the item in 'val'.
1366 typedef void (*process_field_fn)
1367 (type_p f, const struct walk_type_data *p);
1368 typedef void (*func_name_fn)
1369 (type_p s, const struct walk_type_data *p);
1371 /* Parameters for write_types. */
1373 struct write_types_data
1375 const char *prefix;
1376 const char *param_prefix;
1377 const char *subfield_marker_routine;
1378 const char *marker_routine;
1379 const char *reorder_note_routine;
1380 const char *comment;
1383 static void output_escaped_param (struct walk_type_data *d,
1384 const char *, const char *);
1385 static void output_mangled_typename (outf_p, type_p);
1386 static void walk_type (type_p t, struct walk_type_data *d);
1387 static void write_func_for_structure
1388 (type_p orig_s, type_p s, type_p * param,
1389 const struct write_types_data *wtd);
1390 static void write_types_process_field
1391 (type_p f, const struct walk_type_data *d);
1392 static void write_types (type_p structures,
1393 type_p param_structs,
1394 const struct write_types_data *wtd);
1395 static void write_types_local_process_field
1396 (type_p f, const struct walk_type_data *d);
1397 static void write_local_func_for_structure
1398 (type_p orig_s, type_p s, type_p * param);
1399 static void write_local (type_p structures,
1400 type_p param_structs);
1401 static void write_enum_defn (type_p structures, type_p param_structs);
1402 static int contains_scalar_p (type_p t);
1403 static void put_mangled_filename (outf_p , const char *);
1404 static void finish_root_table (struct flist *flp, const char *pfx,
1405 const char *tname, const char *lastname,
1406 const char *name);
1407 static void write_root (outf_p , pair_p, type_p, const char *, int,
1408 struct fileloc *, const char *);
1409 static void write_array (outf_p f, pair_p v,
1410 const struct write_types_data *wtd);
1411 static void write_roots (pair_p);
1413 /* Parameters for walk_type. */
1415 struct walk_type_data
1417 process_field_fn process_field;
1418 const void *cookie;
1419 outf_p of;
1420 options_p opt;
1421 const char *val;
1422 const char *prev_val[4];
1423 int indent;
1424 int counter;
1425 struct fileloc *line;
1426 lang_bitmap bitmap;
1427 type_p *param;
1428 int used_length;
1429 type_p orig_s;
1430 const char *reorder_fn;
1431 bool needs_cast_p;
1432 bool fn_wants_lvalue;
1435 /* Print a mangled name representing T to OF. */
1437 static void
1438 output_mangled_typename (outf_p of, type_p t)
1440 if (t == NULL)
1441 oprintf (of, "Z");
1442 else switch (t->kind)
1444 case TYPE_POINTER:
1445 oprintf (of, "P");
1446 output_mangled_typename (of, t->u.p);
1447 break;
1448 case TYPE_SCALAR:
1449 oprintf (of, "I");
1450 break;
1451 case TYPE_STRING:
1452 oprintf (of, "S");
1453 break;
1454 case TYPE_STRUCT:
1455 case TYPE_UNION:
1456 case TYPE_LANG_STRUCT:
1457 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1458 break;
1459 case TYPE_PARAM_STRUCT:
1461 int i;
1462 for (i = 0; i < NUM_PARAM; i++)
1463 if (t->u.param_struct.param[i] != NULL)
1464 output_mangled_typename (of, t->u.param_struct.param[i]);
1465 output_mangled_typename (of, t->u.param_struct.stru);
1467 break;
1468 case TYPE_ARRAY:
1469 gcc_unreachable ();
1473 /* Print PARAM to D->OF processing escapes. D->VAL references the
1474 current object, D->PREV_VAL the object containing the current
1475 object, ONAME is the name of the option and D->LINE is used to
1476 print error messages. */
1478 static void
1479 output_escaped_param (struct walk_type_data *d, const char *param,
1480 const char *oname)
1482 const char *p;
1484 for (p = param; *p; p++)
1485 if (*p != '%')
1486 oprintf (d->of, "%c", *p);
1487 else switch (*++p)
1489 case 'h':
1490 oprintf (d->of, "(%s)", d->prev_val[2]);
1491 break;
1492 case '0':
1493 oprintf (d->of, "(%s)", d->prev_val[0]);
1494 break;
1495 case '1':
1496 oprintf (d->of, "(%s)", d->prev_val[1]);
1497 break;
1498 case 'a':
1500 const char *pp = d->val + strlen (d->val);
1501 while (pp[-1] == ']')
1502 while (*pp != '[')
1503 pp--;
1504 oprintf (d->of, "%s", pp);
1506 break;
1507 default:
1508 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1509 oname, '%', *p);
1513 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1514 which is of type T. Write code to D->OF to constrain execution (at
1515 the point that D->PROCESS_FIELD is called) to the appropriate
1516 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1517 pointers to those objects. D->PREV_VAL lists the objects
1518 containing the current object, D->OPT is a list of options to
1519 apply, D->INDENT is the current indentation level, D->LINE is used
1520 to print error messages, D->BITMAP indicates which languages to
1521 print the structure for, and D->PARAM is the current parameter
1522 (from an enclosing param_is option). */
1524 static void
1525 walk_type (type_p t, struct walk_type_data *d)
1527 const char *length = NULL;
1528 const char *desc = NULL;
1529 int maybe_undef_p = 0;
1530 int use_param_num = -1;
1531 int use_params_p = 0;
1532 options_p oo;
1533 const struct nested_ptr_data *nested_ptr_d = NULL;
1535 d->needs_cast_p = false;
1536 for (oo = d->opt; oo; oo = oo->next)
1537 if (strcmp (oo->name, "length") == 0)
1538 length = oo->info;
1539 else if (strcmp (oo->name, "maybe_undef") == 0)
1540 maybe_undef_p = 1;
1541 else if (strncmp (oo->name, "use_param", 9) == 0
1542 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1543 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1544 else if (strcmp (oo->name, "use_params") == 0)
1545 use_params_p = 1;
1546 else if (strcmp (oo->name, "desc") == 0)
1547 desc = oo->info;
1548 else if (strcmp (oo->name, "nested_ptr") == 0)
1549 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1550 else if (strcmp (oo->name, "dot") == 0)
1552 else if (strcmp (oo->name, "tag") == 0)
1554 else if (strcmp (oo->name, "special") == 0)
1556 else if (strcmp (oo->name, "skip") == 0)
1558 else if (strcmp (oo->name, "default") == 0)
1560 else if (strcmp (oo->name, "descbits") == 0)
1562 else if (strcmp (oo->name, "param_is") == 0)
1564 else if (strncmp (oo->name, "param", 5) == 0
1565 && ISDIGIT (oo->name[5])
1566 && strcmp (oo->name + 6, "_is") == 0)
1568 else if (strcmp (oo->name, "chain_next") == 0)
1570 else if (strcmp (oo->name, "chain_prev") == 0)
1572 else if (strcmp (oo->name, "reorder") == 0)
1574 else
1575 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1577 if (d->used_length)
1578 length = NULL;
1580 if (use_params_p)
1582 int pointer_p = t->kind == TYPE_POINTER;
1584 if (pointer_p)
1585 t = t->u.p;
1586 if (! UNION_OR_STRUCT_P (t))
1587 error_at_line (d->line, "`use_params' option on unimplemented type");
1588 else
1589 t = find_param_structure (t, d->param);
1590 if (pointer_p)
1591 t = create_pointer (t);
1594 if (use_param_num != -1)
1596 if (d->param != NULL && d->param[use_param_num] != NULL)
1598 type_p nt = d->param[use_param_num];
1600 if (t->kind == TYPE_ARRAY)
1601 nt = create_array (nt, t->u.a.len);
1602 else if (length != NULL && t->kind == TYPE_POINTER)
1603 nt = create_pointer (nt);
1604 d->needs_cast_p = (t->kind != TYPE_POINTER
1605 && (nt->kind == TYPE_POINTER
1606 || nt->kind == TYPE_STRING));
1607 t = nt;
1609 else
1610 error_at_line (d->line, "no parameter defined for `%s'",
1611 d->val);
1614 if (maybe_undef_p
1615 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1617 error_at_line (d->line,
1618 "field `%s' has invalid option `maybe_undef_p'\n",
1619 d->val);
1620 return;
1623 switch (t->kind)
1625 case TYPE_SCALAR:
1626 case TYPE_STRING:
1627 d->process_field (t, d);
1628 break;
1630 case TYPE_POINTER:
1632 if (maybe_undef_p
1633 && t->u.p->u.s.line.file == NULL)
1635 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1636 break;
1639 if (! length)
1641 if (! UNION_OR_STRUCT_P (t->u.p)
1642 && t->u.p->kind != TYPE_PARAM_STRUCT)
1644 error_at_line (d->line,
1645 "field `%s' is pointer to unimplemented type",
1646 d->val);
1647 break;
1650 if (nested_ptr_d)
1652 const char *oldprevval2 = d->prev_val[2];
1654 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1656 error_at_line (d->line,
1657 "field `%s' has invalid "
1658 "option `nested_ptr'\n",
1659 d->val);
1660 return;
1663 d->prev_val[2] = d->val;
1664 oprintf (d->of, "%*s{\n", d->indent, "");
1665 d->indent += 2;
1666 d->val = xasprintf ("x%d", d->counter++);
1667 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1668 (nested_ptr_d->type->kind == TYPE_UNION
1669 ? "union" : "struct"),
1670 nested_ptr_d->type->u.s.tag,
1671 d->fn_wants_lvalue ? "" : "const ",
1672 d->val);
1673 oprintf (d->of, "%*s", d->indent + 2, "");
1674 output_escaped_param (d, nested_ptr_d->convert_from,
1675 "nested_ptr");
1676 oprintf (d->of, ";\n");
1678 d->process_field (nested_ptr_d->type, d);
1680 if (d->fn_wants_lvalue)
1682 oprintf (d->of, "%*s%s = ", d->indent, "",
1683 d->prev_val[2]);
1684 d->prev_val[2] = d->val;
1685 output_escaped_param (d, nested_ptr_d->convert_to,
1686 "nested_ptr");
1687 oprintf (d->of, ";\n");
1690 d->indent -= 2;
1691 oprintf (d->of, "%*s}\n", d->indent, "");
1692 d->val = d->prev_val[2];
1693 d->prev_val[2] = oldprevval2;
1695 else
1696 d->process_field (t->u.p, d);
1698 else
1700 int loopcounter = d->counter++;
1701 const char *oldval = d->val;
1702 const char *oldprevval3 = d->prev_val[3];
1703 char *newval;
1705 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1706 d->indent += 2;
1707 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1708 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1709 loopcounter, loopcounter);
1710 output_escaped_param (d, length, "length");
1711 oprintf (d->of, "); i%d++) {\n", loopcounter);
1712 d->indent += 2;
1713 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1714 d->used_length = 1;
1715 d->prev_val[3] = oldval;
1716 walk_type (t->u.p, d);
1717 free (newval);
1718 d->val = oldval;
1719 d->prev_val[3] = oldprevval3;
1720 d->used_length = 0;
1721 d->indent -= 2;
1722 oprintf (d->of, "%*s}\n", d->indent, "");
1723 d->process_field(t, d);
1724 d->indent -= 2;
1725 oprintf (d->of, "%*s}\n", d->indent, "");
1728 break;
1730 case TYPE_ARRAY:
1732 int loopcounter = d->counter++;
1733 const char *oldval = d->val;
1734 char *newval;
1736 /* If it's an array of scalars, we optimize by not generating
1737 any code. */
1738 if (t->u.a.p->kind == TYPE_SCALAR)
1739 break;
1741 oprintf (d->of, "%*s{\n", d->indent, "");
1742 d->indent += 2;
1743 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1744 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1745 loopcounter, loopcounter);
1746 if (length)
1747 output_escaped_param (d, length, "length");
1748 else
1749 oprintf (d->of, "%s", t->u.a.len);
1750 oprintf (d->of, "); i%d++) {\n", loopcounter);
1751 d->indent += 2;
1752 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1753 d->used_length = 1;
1754 walk_type (t->u.a.p, d);
1755 free (newval);
1756 d->used_length = 0;
1757 d->val = oldval;
1758 d->indent -= 2;
1759 oprintf (d->of, "%*s}\n", d->indent, "");
1760 d->indent -= 2;
1761 oprintf (d->of, "%*s}\n", d->indent, "");
1763 break;
1765 case TYPE_STRUCT:
1766 case TYPE_UNION:
1768 pair_p f;
1769 const char *oldval = d->val;
1770 const char *oldprevval1 = d->prev_val[1];
1771 const char *oldprevval2 = d->prev_val[2];
1772 const int union_p = t->kind == TYPE_UNION;
1773 int seen_default_p = 0;
1774 options_p o;
1776 if (! t->u.s.line.file)
1777 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1779 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1781 error_at_line (d->line,
1782 "structure `%s' defined for mismatching languages",
1783 t->u.s.tag);
1784 error_at_line (&t->u.s.line, "one structure defined here");
1787 /* Some things may also be defined in the structure's options. */
1788 for (o = t->u.s.opt; o; o = o->next)
1789 if (! desc && strcmp (o->name, "desc") == 0)
1790 desc = o->info;
1792 d->prev_val[2] = oldval;
1793 d->prev_val[1] = oldprevval2;
1794 if (union_p)
1796 if (desc == NULL)
1798 error_at_line (d->line, "missing `desc' option for union `%s'",
1799 t->u.s.tag);
1800 desc = "1";
1802 oprintf (d->of, "%*sswitch (", d->indent, "");
1803 output_escaped_param (d, desc, "desc");
1804 oprintf (d->of, ")\n");
1805 d->indent += 2;
1806 oprintf (d->of, "%*s{\n", d->indent, "");
1808 for (f = t->u.s.fields; f; f = f->next)
1810 options_p oo;
1811 const char *dot = ".";
1812 const char *tagid = NULL;
1813 int skip_p = 0;
1814 int default_p = 0;
1815 int use_param_p = 0;
1816 char *newval;
1818 d->reorder_fn = NULL;
1819 for (oo = f->opt; oo; oo = oo->next)
1820 if (strcmp (oo->name, "dot") == 0)
1821 dot = oo->info;
1822 else if (strcmp (oo->name, "tag") == 0)
1823 tagid = oo->info;
1824 else if (strcmp (oo->name, "skip") == 0)
1825 skip_p = 1;
1826 else if (strcmp (oo->name, "default") == 0)
1827 default_p = 1;
1828 else if (strcmp (oo->name, "reorder") == 0)
1829 d->reorder_fn = oo->info;
1830 else if (strncmp (oo->name, "use_param", 9) == 0
1831 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1832 use_param_p = 1;
1834 if (skip_p)
1835 continue;
1837 if (union_p && tagid)
1839 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1840 d->indent += 2;
1842 else if (union_p && default_p)
1844 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1845 d->indent += 2;
1846 seen_default_p = 1;
1848 else if (! union_p && (default_p || tagid))
1849 error_at_line (d->line,
1850 "can't use `%s' outside a union on field `%s'",
1851 default_p ? "default" : "tag", f->name);
1852 else if (union_p && ! (default_p || tagid)
1853 && f->type->kind == TYPE_SCALAR)
1855 fprintf (stderr,
1856 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1857 d->line->file, d->line->line, f->name);
1858 continue;
1860 else if (union_p && ! (default_p || tagid))
1861 error_at_line (d->line,
1862 "field `%s' is missing `tag' or `default' option",
1863 f->name);
1865 d->line = &f->line;
1866 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1867 d->opt = f->opt;
1868 d->used_length = false;
1870 if (union_p && use_param_p && d->param == NULL)
1871 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1872 else
1873 walk_type (f->type, d);
1875 free (newval);
1877 if (union_p)
1879 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1880 d->indent -= 2;
1883 d->reorder_fn = NULL;
1885 d->val = oldval;
1886 d->prev_val[1] = oldprevval1;
1887 d->prev_val[2] = oldprevval2;
1889 if (union_p && ! seen_default_p)
1891 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1892 oprintf (d->of, "%*s break;\n", d->indent, "");
1894 if (union_p)
1896 oprintf (d->of, "%*s}\n", d->indent, "");
1897 d->indent -= 2;
1900 break;
1902 case TYPE_LANG_STRUCT:
1904 type_p nt;
1905 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1906 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1907 break;
1908 if (nt == NULL)
1909 error_at_line (d->line, "structure `%s' differs between languages",
1910 t->u.s.tag);
1911 else
1912 walk_type (nt, d);
1914 break;
1916 case TYPE_PARAM_STRUCT:
1918 type_p *oldparam = d->param;
1920 d->param = t->u.param_struct.param;
1921 walk_type (t->u.param_struct.stru, d);
1922 d->param = oldparam;
1924 break;
1926 default:
1927 gcc_unreachable ();
1931 /* process_field routine for marking routines. */
1933 static void
1934 write_types_process_field (type_p f, const struct walk_type_data *d)
1936 const struct write_types_data *wtd;
1937 const char *cast = d->needs_cast_p ? "(void *)" : "";
1938 wtd = (const struct write_types_data *) d->cookie;
1940 switch (f->kind)
1942 case TYPE_POINTER:
1943 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1944 wtd->subfield_marker_routine, cast, d->val);
1945 if (wtd->param_prefix)
1947 oprintf (d->of, ", %s", d->prev_val[3]);
1948 if (d->orig_s)
1950 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1951 output_mangled_typename (d->of, d->orig_s);
1953 else
1954 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1956 if (f->u.p->kind == TYPE_PARAM_STRUCT
1957 && f->u.p->u.s.line.file != NULL)
1959 oprintf (d->of, ", gt_e_");
1960 output_mangled_typename (d->of, f);
1962 else if (UNION_OR_STRUCT_P (f)
1963 && f->u.p->u.s.line.file != NULL)
1965 oprintf (d->of, ", gt_ggc_e_");
1966 output_mangled_typename (d->of, f);
1968 else
1969 oprintf (d->of, ", gt_types_enum_last");
1971 oprintf (d->of, ");\n");
1972 if (d->reorder_fn && wtd->reorder_note_routine)
1973 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1974 wtd->reorder_note_routine, cast, d->val,
1975 d->prev_val[3], d->reorder_fn);
1976 break;
1978 case TYPE_STRING:
1979 if (wtd->param_prefix == NULL)
1980 break;
1982 case TYPE_STRUCT:
1983 case TYPE_UNION:
1984 case TYPE_LANG_STRUCT:
1985 case TYPE_PARAM_STRUCT:
1986 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1987 output_mangled_typename (d->of, f);
1988 oprintf (d->of, " (%s%s);\n", cast, d->val);
1989 if (d->reorder_fn && wtd->reorder_note_routine)
1990 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1991 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1992 d->reorder_fn);
1993 break;
1995 case TYPE_SCALAR:
1996 break;
1998 default:
1999 gcc_unreachable ();
2003 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
2005 static void
2006 output_type_enum (outf_p of, type_p s)
2008 if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2010 oprintf (of, ", gt_e_");
2011 output_mangled_typename (of, s);
2013 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2015 oprintf (of, ", gt_ggc_e_");
2016 output_mangled_typename (of, s);
2018 else
2019 oprintf (of, ", gt_types_enum_last");
2022 /* For S, a structure that's part of ORIG_S, and using parameters
2023 PARAM, write out a routine that:
2024 - Takes a parameter, a void * but actually of type *S
2025 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2026 field of S or its substructures and (in some cases) things
2027 that are pointed to by S.
2030 static void
2031 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2032 const struct write_types_data *wtd)
2034 const char *fn = s->u.s.line.file;
2035 int i;
2036 const char *chain_next = NULL;
2037 const char *chain_prev = NULL;
2038 options_p opt;
2039 struct walk_type_data d;
2041 /* This is a hack, and not the good kind either. */
2042 for (i = NUM_PARAM - 1; i >= 0; i--)
2043 if (param && param[i] && param[i]->kind == TYPE_POINTER
2044 && UNION_OR_STRUCT_P (param[i]->u.p))
2045 fn = param[i]->u.p->u.s.line.file;
2047 memset (&d, 0, sizeof (d));
2048 d.of = get_output_file_with_visibility (fn);
2050 for (opt = s->u.s.opt; opt; opt = opt->next)
2051 if (strcmp (opt->name, "chain_next") == 0)
2052 chain_next = opt->info;
2053 else if (strcmp (opt->name, "chain_prev") == 0)
2054 chain_prev = opt->info;
2056 if (chain_prev != NULL && chain_next == NULL)
2057 error_at_line (&s->u.s.line, "chain_prev without chain_next");
2059 d.process_field = write_types_process_field;
2060 d.cookie = wtd;
2061 d.orig_s = orig_s;
2062 d.opt = s->u.s.opt;
2063 d.line = &s->u.s.line;
2064 d.bitmap = s->u.s.bitmap;
2065 d.param = param;
2066 d.prev_val[0] = "*x";
2067 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2068 d.prev_val[3] = "x";
2069 d.val = "(*x)";
2071 oprintf (d.of, "\n");
2072 oprintf (d.of, "void\n");
2073 if (param == NULL)
2074 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2075 else
2077 oprintf (d.of, "gt_%s_", wtd->prefix);
2078 output_mangled_typename (d.of, orig_s);
2080 oprintf (d.of, " (void *x_p)\n");
2081 oprintf (d.of, "{\n");
2082 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2083 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2084 chain_next == NULL ? "const " : "",
2085 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2086 if (chain_next != NULL)
2087 oprintf (d.of, " %s %s * xlimit = x;\n",
2088 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2089 if (chain_next == NULL)
2091 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2092 if (wtd->param_prefix)
2094 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2095 output_mangled_typename (d.of, orig_s);
2096 output_type_enum (d.of, orig_s);
2098 oprintf (d.of, "))\n");
2100 else
2102 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2103 if (wtd->param_prefix)
2105 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2106 output_mangled_typename (d.of, orig_s);
2107 output_type_enum (d.of, orig_s);
2109 oprintf (d.of, "))\n");
2110 oprintf (d.of, " xlimit = (");
2111 d.prev_val[2] = "*xlimit";
2112 output_escaped_param (&d, chain_next, "chain_next");
2113 oprintf (d.of, ");\n");
2114 if (chain_prev != NULL)
2116 oprintf (d.of, " if (x != xlimit)\n");
2117 oprintf (d.of, " for (;;)\n");
2118 oprintf (d.of, " {\n");
2119 oprintf (d.of, " %s %s * const xprev = (",
2120 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2122 d.prev_val[2] = "*x";
2123 output_escaped_param (&d, chain_prev, "chain_prev");
2124 oprintf (d.of, ");\n");
2125 oprintf (d.of, " if (xprev == NULL) break;\n");
2126 oprintf (d.of, " x = xprev;\n");
2127 oprintf (d.of, " (void) %s (xprev",
2128 wtd->marker_routine);
2129 if (wtd->param_prefix)
2131 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2132 output_mangled_typename (d.of, orig_s);
2133 output_type_enum (d.of, orig_s);
2135 oprintf (d.of, ");\n");
2136 oprintf (d.of, " }\n");
2138 oprintf (d.of, " while (x != xlimit)\n");
2140 oprintf (d.of, " {\n");
2142 d.prev_val[2] = "*x";
2143 d.indent = 6;
2144 walk_type (s, &d);
2146 if (chain_next != NULL)
2148 oprintf (d.of, " x = (");
2149 output_escaped_param (&d, chain_next, "chain_next");
2150 oprintf (d.of, ");\n");
2153 oprintf (d.of, " }\n");
2154 oprintf (d.of, "}\n");
2157 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2159 static void
2160 write_types (type_p structures, type_p param_structs,
2161 const struct write_types_data *wtd)
2163 type_p s;
2165 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2166 for (s = structures; s; s = s->next)
2167 if (s->gc_used == GC_POINTED_TO
2168 || s->gc_used == GC_MAYBE_POINTED_TO)
2170 options_p opt;
2172 if (s->gc_used == GC_MAYBE_POINTED_TO
2173 && s->u.s.line.file == NULL)
2174 continue;
2176 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2177 output_mangled_typename (header_file, s);
2178 oprintf (header_file, "(X) do { \\\n");
2179 oprintf (header_file,
2180 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2181 s->u.s.tag);
2182 oprintf (header_file,
2183 " } while (0)\n");
2185 for (opt = s->u.s.opt; opt; opt = opt->next)
2186 if (strcmp (opt->name, "ptr_alias") == 0)
2188 type_p t = (type_p) opt->info;
2189 if (t->kind == TYPE_STRUCT
2190 || t->kind == TYPE_UNION
2191 || t->kind == TYPE_LANG_STRUCT)
2192 oprintf (header_file,
2193 "#define gt_%sx_%s gt_%sx_%s\n",
2194 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2195 else
2196 error_at_line (&s->u.s.line,
2197 "structure alias is not a structure");
2198 break;
2200 if (opt)
2201 continue;
2203 /* Declare the marker procedure only once. */
2204 oprintf (header_file,
2205 "extern void gt_%sx_%s (void *);\n",
2206 wtd->prefix, s->u.s.tag);
2208 if (s->u.s.line.file == NULL)
2210 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2211 s->u.s.tag);
2212 continue;
2215 if (s->kind == TYPE_LANG_STRUCT)
2217 type_p ss;
2218 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2219 write_func_for_structure (s, ss, NULL, wtd);
2221 else
2222 write_func_for_structure (s, s, NULL, wtd);
2225 for (s = param_structs; s; s = s->next)
2226 if (s->gc_used == GC_POINTED_TO)
2228 type_p * param = s->u.param_struct.param;
2229 type_p stru = s->u.param_struct.stru;
2231 /* Declare the marker procedure. */
2232 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2233 output_mangled_typename (header_file, s);
2234 oprintf (header_file, " (void *);\n");
2236 if (stru->u.s.line.file == NULL)
2238 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2239 s->u.s.tag);
2240 continue;
2243 if (stru->kind == TYPE_LANG_STRUCT)
2245 type_p ss;
2246 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2247 write_func_for_structure (s, ss, param, wtd);
2249 else
2250 write_func_for_structure (s, stru, param, wtd);
2254 static const struct write_types_data ggc_wtd =
2256 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2257 "GC marker procedures. "
2260 static const struct write_types_data pch_wtd =
2262 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2263 "gt_pch_note_reorder",
2264 "PCH type-walking procedures. "
2267 /* Write out the local pointer-walking routines. */
2269 /* process_field routine for local pointer-walking. */
2271 static void
2272 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2274 switch (f->kind)
2276 case TYPE_POINTER:
2277 case TYPE_STRUCT:
2278 case TYPE_UNION:
2279 case TYPE_LANG_STRUCT:
2280 case TYPE_PARAM_STRUCT:
2281 case TYPE_STRING:
2282 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2283 d->prev_val[3]);
2284 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2285 break;
2287 case TYPE_SCALAR:
2288 break;
2290 default:
2291 gcc_unreachable ();
2295 /* For S, a structure that's part of ORIG_S, and using parameters
2296 PARAM, write out a routine that:
2297 - Is of type gt_note_pointers
2298 - Calls PROCESS_FIELD on each field of S or its substructures.
2301 static void
2302 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2304 const char *fn = s->u.s.line.file;
2305 int i;
2306 struct walk_type_data d;
2308 /* This is a hack, and not the good kind either. */
2309 for (i = NUM_PARAM - 1; i >= 0; i--)
2310 if (param && param[i] && param[i]->kind == TYPE_POINTER
2311 && UNION_OR_STRUCT_P (param[i]->u.p))
2312 fn = param[i]->u.p->u.s.line.file;
2314 memset (&d, 0, sizeof (d));
2315 d.of = get_output_file_with_visibility (fn);
2317 d.process_field = write_types_local_process_field;
2318 d.opt = s->u.s.opt;
2319 d.line = &s->u.s.line;
2320 d.bitmap = s->u.s.bitmap;
2321 d.param = param;
2322 d.prev_val[0] = d.prev_val[2] = "*x";
2323 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2324 d.prev_val[3] = "x";
2325 d.val = "(*x)";
2326 d.fn_wants_lvalue = true;
2328 oprintf (d.of, "\n");
2329 oprintf (d.of, "void\n");
2330 oprintf (d.of, "gt_pch_p_");
2331 output_mangled_typename (d.of, orig_s);
2332 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2333 "\tvoid *x_p,\n"
2334 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2335 "\tATTRIBUTE_UNUSED void *cookie)\n");
2336 oprintf (d.of, "{\n");
2337 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2338 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2339 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2340 d.indent = 2;
2341 walk_type (s, &d);
2342 oprintf (d.of, "}\n");
2345 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2347 static void
2348 write_local (type_p structures, type_p param_structs)
2350 type_p s;
2352 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2353 for (s = structures; s; s = s->next)
2354 if (s->gc_used == GC_POINTED_TO
2355 || s->gc_used == GC_MAYBE_POINTED_TO)
2357 options_p opt;
2359 if (s->u.s.line.file == NULL)
2360 continue;
2362 for (opt = s->u.s.opt; opt; opt = opt->next)
2363 if (strcmp (opt->name, "ptr_alias") == 0)
2365 type_p t = (type_p) opt->info;
2366 if (t->kind == TYPE_STRUCT
2367 || t->kind == TYPE_UNION
2368 || t->kind == TYPE_LANG_STRUCT)
2370 oprintf (header_file, "#define gt_pch_p_");
2371 output_mangled_typename (header_file, s);
2372 oprintf (header_file, " gt_pch_p_");
2373 output_mangled_typename (header_file, t);
2374 oprintf (header_file, "\n");
2376 else
2377 error_at_line (&s->u.s.line,
2378 "structure alias is not a structure");
2379 break;
2381 if (opt)
2382 continue;
2384 /* Declare the marker procedure only once. */
2385 oprintf (header_file, "extern void gt_pch_p_");
2386 output_mangled_typename (header_file, s);
2387 oprintf (header_file,
2388 "\n (void *, void *, gt_pointer_operator, void *);\n");
2390 if (s->kind == TYPE_LANG_STRUCT)
2392 type_p ss;
2393 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2394 write_local_func_for_structure (s, ss, NULL);
2396 else
2397 write_local_func_for_structure (s, s, NULL);
2400 for (s = param_structs; s; s = s->next)
2401 if (s->gc_used == GC_POINTED_TO)
2403 type_p * param = s->u.param_struct.param;
2404 type_p stru = s->u.param_struct.stru;
2406 /* Declare the marker procedure. */
2407 oprintf (header_file, "extern void gt_pch_p_");
2408 output_mangled_typename (header_file, s);
2409 oprintf (header_file,
2410 "\n (void *, void *, gt_pointer_operator, void *);\n");
2412 if (stru->u.s.line.file == NULL)
2414 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2415 s->u.s.tag);
2416 continue;
2419 if (stru->kind == TYPE_LANG_STRUCT)
2421 type_p ss;
2422 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2423 write_local_func_for_structure (s, ss, param);
2425 else
2426 write_local_func_for_structure (s, stru, param);
2430 /* Write out the 'enum' definition for gt_types_enum. */
2432 static void
2433 write_enum_defn (type_p structures, type_p param_structs)
2435 type_p s;
2437 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2438 oprintf (header_file, "enum gt_types_enum {\n");
2439 for (s = structures; s; s = s->next)
2440 if (s->gc_used == GC_POINTED_TO
2441 || s->gc_used == GC_MAYBE_POINTED_TO)
2443 if (s->gc_used == GC_MAYBE_POINTED_TO
2444 && s->u.s.line.file == NULL)
2445 continue;
2447 oprintf (header_file, " gt_ggc_e_");
2448 output_mangled_typename (header_file, s);
2449 oprintf (header_file, ", \n");
2451 for (s = param_structs; s; s = s->next)
2452 if (s->gc_used == GC_POINTED_TO)
2454 oprintf (header_file, " gt_e_");
2455 output_mangled_typename (header_file, s);
2456 oprintf (header_file, ", \n");
2458 oprintf (header_file, " gt_types_enum_last\n");
2459 oprintf (header_file, "};\n");
2462 /* Might T contain any non-pointer elements? */
2464 static int
2465 contains_scalar_p (type_p t)
2467 switch (t->kind)
2469 case TYPE_STRING:
2470 case TYPE_POINTER:
2471 return 0;
2472 case TYPE_ARRAY:
2473 return contains_scalar_p (t->u.a.p);
2474 default:
2475 /* Could also check for structures that have no non-pointer
2476 fields, but there aren't enough of those to worry about. */
2477 return 1;
2481 /* Mangle FN and print it to F. */
2483 static void
2484 put_mangled_filename (outf_p f, const char *fn)
2486 const char *name = get_output_file_name (fn);
2487 for (; *name != 0; name++)
2488 if (ISALNUM (*name))
2489 oprintf (f, "%c", *name);
2490 else
2491 oprintf (f, "%c", '_');
2494 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2495 LASTNAME, and NAME are all strings to insert in various places in
2496 the resulting code. */
2498 static void
2499 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2500 const char *tname, const char *name)
2502 struct flist *fli2;
2504 for (fli2 = flp; fli2; fli2 = fli2->next)
2505 if (fli2->started_p)
2507 oprintf (fli2->f, " %s\n", lastname);
2508 oprintf (fli2->f, "};\n\n");
2511 for (fli2 = flp; fli2; fli2 = fli2->next)
2512 if (fli2->started_p)
2514 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2515 int fnum;
2517 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2518 if (bitmap & 1)
2520 oprintf (base_files[fnum],
2521 "extern const struct %s gt_%s_",
2522 tname, pfx);
2523 put_mangled_filename (base_files[fnum], fli2->name);
2524 oprintf (base_files[fnum], "[];\n");
2529 size_t fnum;
2530 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2531 oprintf (base_files [fnum],
2532 "const struct %s * const %s[] = {\n",
2533 tname, name);
2537 for (fli2 = flp; fli2; fli2 = fli2->next)
2538 if (fli2->started_p)
2540 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2541 int fnum;
2543 fli2->started_p = 0;
2545 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2546 if (bitmap & 1)
2548 oprintf (base_files[fnum], " gt_%s_", pfx);
2549 put_mangled_filename (base_files[fnum], fli2->name);
2550 oprintf (base_files[fnum], ",\n");
2555 size_t fnum;
2556 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2558 oprintf (base_files[fnum], " NULL\n");
2559 oprintf (base_files[fnum], "};\n");
2564 /* Write out to F the table entry and any marker routines needed to
2565 mark NAME as TYPE. The original variable is V, at LINE.
2566 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2567 is nonzero iff we are building the root table for hash table caches. */
2569 static void
2570 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2571 struct fileloc *line, const char *if_marked)
2573 switch (type->kind)
2575 case TYPE_STRUCT:
2577 pair_p fld;
2578 for (fld = type->u.s.fields; fld; fld = fld->next)
2580 int skip_p = 0;
2581 const char *desc = NULL;
2582 options_p o;
2584 for (o = fld->opt; o; o = o->next)
2585 if (strcmp (o->name, "skip") == 0)
2586 skip_p = 1;
2587 else if (strcmp (o->name, "desc") == 0)
2588 desc = o->info;
2589 else
2590 error_at_line (line,
2591 "field `%s' of global `%s' has unknown option `%s'",
2592 fld->name, name, o->name);
2594 if (skip_p)
2595 continue;
2596 else if (desc && fld->type->kind == TYPE_UNION)
2598 pair_p validf = NULL;
2599 pair_p ufld;
2601 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2603 const char *tag = NULL;
2604 options_p oo;
2606 for (oo = ufld->opt; oo; oo = oo->next)
2607 if (strcmp (oo->name, "tag") == 0)
2608 tag = oo->info;
2609 if (tag == NULL || strcmp (tag, desc) != 0)
2610 continue;
2611 if (validf != NULL)
2612 error_at_line (line,
2613 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2614 name, fld->name, validf->name,
2615 name, fld->name, ufld->name,
2616 tag);
2617 validf = ufld;
2619 if (validf != NULL)
2621 char *newname;
2622 newname = xasprintf ("%s.%s.%s",
2623 name, fld->name, validf->name);
2624 write_root (f, v, validf->type, newname, 0, line,
2625 if_marked);
2626 free (newname);
2629 else if (desc)
2630 error_at_line (line,
2631 "global `%s.%s' has `desc' option but is not union",
2632 name, fld->name);
2633 else
2635 char *newname;
2636 newname = xasprintf ("%s.%s", name, fld->name);
2637 write_root (f, v, fld->type, newname, 0, line, if_marked);
2638 free (newname);
2642 break;
2644 case TYPE_ARRAY:
2646 char *newname;
2647 newname = xasprintf ("%s[0]", name);
2648 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2649 free (newname);
2651 break;
2653 case TYPE_POINTER:
2655 type_p ap, tp;
2657 oprintf (f, " {\n");
2658 oprintf (f, " &%s,\n", name);
2659 oprintf (f, " 1");
2661 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2662 if (ap->u.a.len[0])
2663 oprintf (f, " * (%s)", ap->u.a.len);
2664 else if (ap == v->type)
2665 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2666 oprintf (f, ",\n");
2667 oprintf (f, " sizeof (%s", v->name);
2668 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2669 oprintf (f, "[0]");
2670 oprintf (f, "),\n");
2672 tp = type->u.p;
2674 if (! has_length && UNION_OR_STRUCT_P (tp))
2676 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2677 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2679 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2681 oprintf (f, " &gt_ggc_m_");
2682 output_mangled_typename (f, tp);
2683 oprintf (f, ",\n &gt_pch_n_");
2684 output_mangled_typename (f, tp);
2686 else if (has_length
2687 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2689 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2690 oprintf (f, " &gt_pch_na_%s", name);
2692 else
2694 error_at_line (line,
2695 "global `%s' is pointer to unimplemented type",
2696 name);
2698 if (if_marked)
2699 oprintf (f, ",\n &%s", if_marked);
2700 oprintf (f, "\n },\n");
2702 break;
2704 case TYPE_STRING:
2706 oprintf (f, " {\n");
2707 oprintf (f, " &%s,\n", name);
2708 oprintf (f, " 1, \n");
2709 oprintf (f, " sizeof (%s),\n", v->name);
2710 oprintf (f, " &gt_ggc_m_S,\n");
2711 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2712 oprintf (f, " },\n");
2714 break;
2716 case TYPE_SCALAR:
2717 break;
2719 default:
2720 error_at_line (line,
2721 "global `%s' is unimplemented type",
2722 name);
2726 /* This generates a routine to walk an array. */
2728 static void
2729 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2731 struct walk_type_data d;
2732 char *prevval3;
2734 memset (&d, 0, sizeof (d));
2735 d.of = f;
2736 d.cookie = wtd;
2737 d.indent = 2;
2738 d.line = &v->line;
2739 d.opt = v->opt;
2740 d.bitmap = get_base_file_bitmap (v->line.file);
2741 d.param = NULL;
2743 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2745 if (wtd->param_prefix)
2747 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2748 oprintf (f,
2749 " (void *, void *, gt_pointer_operator, void *);\n");
2750 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2751 wtd->param_prefix, v->name);
2752 oprintf (d.of,
2753 " ATTRIBUTE_UNUSED void *x_p,\n"
2754 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2755 " ATTRIBUTE_UNUSED void * cookie)\n");
2756 oprintf (d.of, "{\n");
2757 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2758 d.process_field = write_types_local_process_field;
2759 walk_type (v->type, &d);
2760 oprintf (f, "}\n\n");
2763 d.opt = v->opt;
2764 oprintf (f, "static void gt_%sa_%s (void *);\n",
2765 wtd->prefix, v->name);
2766 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2767 wtd->prefix, v->name);
2768 oprintf (f, "{\n");
2769 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2770 d.process_field = write_types_process_field;
2771 walk_type (v->type, &d);
2772 free (prevval3);
2773 oprintf (f, "}\n\n");
2776 /* Output a table describing the locations and types of VARIABLES. */
2778 static void
2779 write_roots (pair_p variables)
2781 pair_p v;
2782 struct flist *flp = NULL;
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 const char *length = NULL;
2789 int deletable_p = 0;
2790 options_p o;
2792 for (o = v->opt; o; o = o->next)
2793 if (strcmp (o->name, "length") == 0)
2794 length = o->info;
2795 else if (strcmp (o->name, "deletable") == 0)
2796 deletable_p = 1;
2797 else if (strcmp (o->name, "param_is") == 0)
2799 else if (strncmp (o->name, "param", 5) == 0
2800 && ISDIGIT (o->name[5])
2801 && strcmp (o->name + 6, "_is") == 0)
2803 else if (strcmp (o->name, "if_marked") == 0)
2805 else
2806 error_at_line (&v->line,
2807 "global `%s' has unknown option `%s'",
2808 v->name, o->name);
2810 for (fli = flp; fli; fli = fli->next)
2811 if (fli->f == f)
2812 break;
2813 if (fli == NULL)
2815 fli = XNEW (struct flist);
2816 fli->f = f;
2817 fli->next = flp;
2818 fli->started_p = 0;
2819 fli->name = v->line.file;
2820 flp = fli;
2822 oprintf (f, "\n/* GC roots. */\n\n");
2825 if (! deletable_p
2826 && length
2827 && v->type->kind == TYPE_POINTER
2828 && (v->type->u.p->kind == TYPE_POINTER
2829 || v->type->u.p->kind == TYPE_STRUCT))
2831 write_array (f, v, &ggc_wtd);
2832 write_array (f, v, &pch_wtd);
2836 for (v = variables; v; v = v->next)
2838 outf_p f = get_output_file_with_visibility (v->line.file);
2839 struct flist *fli;
2840 int skip_p = 0;
2841 int length_p = 0;
2842 options_p o;
2844 for (o = v->opt; o; o = o->next)
2845 if (strcmp (o->name, "length") == 0)
2846 length_p = 1;
2847 else if (strcmp (o->name, "deletable") == 0
2848 || strcmp (o->name, "if_marked") == 0)
2849 skip_p = 1;
2851 if (skip_p)
2852 continue;
2854 for (fli = flp; fli; fli = fli->next)
2855 if (fli->f == f)
2856 break;
2857 if (! fli->started_p)
2859 fli->started_p = 1;
2861 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2862 put_mangled_filename (f, v->line.file);
2863 oprintf (f, "[] = {\n");
2866 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2869 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2870 "gt_ggc_rtab");
2872 for (v = variables; v; v = v->next)
2874 outf_p f = get_output_file_with_visibility (v->line.file);
2875 struct flist *fli;
2876 int skip_p = 1;
2877 options_p o;
2879 for (o = v->opt; o; o = o->next)
2880 if (strcmp (o->name, "deletable") == 0)
2881 skip_p = 0;
2882 else if (strcmp (o->name, "if_marked") == 0)
2883 skip_p = 1;
2885 if (skip_p)
2886 continue;
2888 for (fli = flp; fli; fli = fli->next)
2889 if (fli->f == f)
2890 break;
2891 if (! fli->started_p)
2893 fli->started_p = 1;
2895 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2896 put_mangled_filename (f, v->line.file);
2897 oprintf (f, "[] = {\n");
2900 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2901 v->name, v->name);
2904 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2905 "gt_ggc_deletable_rtab");
2907 for (v = variables; v; v = v->next)
2909 outf_p f = get_output_file_with_visibility (v->line.file);
2910 struct flist *fli;
2911 const char *if_marked = NULL;
2912 int length_p = 0;
2913 options_p o;
2915 for (o = v->opt; o; o = o->next)
2916 if (strcmp (o->name, "length") == 0)
2917 length_p = 1;
2918 else if (strcmp (o->name, "if_marked") == 0)
2919 if_marked = o->info;
2921 if (if_marked == NULL)
2922 continue;
2924 if (v->type->kind != TYPE_POINTER
2925 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2926 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2928 error_at_line (&v->line, "if_marked option used but not hash table");
2929 continue;
2932 for (fli = flp; fli; fli = fli->next)
2933 if (fli->f == f)
2934 break;
2935 if (! fli->started_p)
2937 fli->started_p = 1;
2939 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2940 put_mangled_filename (f, v->line.file);
2941 oprintf (f, "[] = {\n");
2944 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2945 v->name, length_p, &v->line, if_marked);
2948 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2949 "gt_ggc_cache_rtab");
2951 for (v = variables; v; v = v->next)
2953 outf_p f = get_output_file_with_visibility (v->line.file);
2954 struct flist *fli;
2955 int length_p = 0;
2956 int if_marked_p = 0;
2957 options_p o;
2959 for (o = v->opt; o; o = o->next)
2960 if (strcmp (o->name, "length") == 0)
2961 length_p = 1;
2962 else if (strcmp (o->name, "if_marked") == 0)
2963 if_marked_p = 1;
2965 if (! if_marked_p)
2966 continue;
2968 for (fli = flp; fli; fli = fli->next)
2969 if (fli->f == f)
2970 break;
2971 if (! fli->started_p)
2973 fli->started_p = 1;
2975 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2976 put_mangled_filename (f, v->line.file);
2977 oprintf (f, "[] = {\n");
2980 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2983 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2984 "gt_pch_cache_rtab");
2986 for (v = variables; v; v = v->next)
2988 outf_p f = get_output_file_with_visibility (v->line.file);
2989 struct flist *fli;
2990 int skip_p = 0;
2991 options_p o;
2993 for (o = v->opt; o; o = o->next)
2994 if (strcmp (o->name, "deletable") == 0
2995 || strcmp (o->name, "if_marked") == 0)
2996 skip_p = 1;
2998 if (skip_p)
2999 continue;
3001 if (! contains_scalar_p (v->type))
3002 continue;
3004 for (fli = flp; fli; fli = fli->next)
3005 if (fli->f == f)
3006 break;
3007 if (! fli->started_p)
3009 fli->started_p = 1;
3011 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3012 put_mangled_filename (f, v->line.file);
3013 oprintf (f, "[] = {\n");
3016 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3017 v->name, v->name);
3020 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3021 "gt_pch_scalar_rtab");
3025 extern int main (int argc, char **argv);
3027 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
3029 unsigned i;
3030 static struct fileloc pos = { __FILE__, __LINE__ };
3031 unsigned j;
3033 gen_rtx_next ();
3035 srcdir_len = strlen (srcdir);
3037 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3038 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3039 do_scalar_typedef ("double_int", &pos);
3040 do_scalar_typedef ("uint8", &pos);
3041 do_scalar_typedef ("jword", &pos);
3042 do_scalar_typedef ("JCF_u2", &pos);
3043 #ifdef USE_MAPPED_LOCATION
3044 do_scalar_typedef ("location_t", &pos);
3045 do_scalar_typedef ("source_locus", &pos);
3046 #endif
3047 do_scalar_typedef ("void", &pos);
3049 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3051 do_typedef ("HARD_REG_SET", create_array (
3052 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3053 "2"), &pos);
3055 for (i = 0; i < NUM_GT_FILES; i++)
3057 int dupflag = 0;
3058 /* Omit if already seen. */
3059 for (j = 0; j < i; j++)
3061 if (!strcmp (all_files[i], all_files[j]))
3063 dupflag = 1;
3064 break;
3067 if (!dupflag)
3068 parse_file (all_files[i]);
3069 #ifndef USE_MAPPED_LOCATION
3070 /* temporary kludge - gengtype doesn't handle conditionals.
3071 Manually add source_locus *after* we've processed input.h. */
3072 if (i == 0)
3073 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3074 #endif
3077 if (hit_error != 0)
3078 exit (1);
3080 set_gc_used (variables);
3082 open_base_files ();
3083 write_enum_defn (structures, param_structs);
3084 write_types (structures, param_structs, &ggc_wtd);
3085 write_types (structures, param_structs, &pch_wtd);
3086 write_local (structures, param_structs);
3087 write_roots (variables);
3088 write_rtx_next ();
3089 close_output_files ();
3091 return (hit_error != 0);