* config/xtensa/elf.h (HANDLE_PRAGMA_PACK_PUSH_POP): Define.
[official-gcc.git] / gcc / gengtype.c
blob1464c5f26af75340ae018b57b89ee050e585288d
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 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 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 2, 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 COPYING. If not, write to the Free\n",
1037 "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1038 "02110-1301, USA. */\n",
1039 "\n",
1040 "/* This file is machine generated. Do not edit. */\n"
1042 outf_p f;
1043 size_t i;
1045 f = XCNEW (struct outf);
1046 f->next = output_files;
1047 f->name = oname;
1048 output_files = f;
1050 oprintf (f, "/* Type information for %s.\n", name);
1051 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1052 oprintf (f, "%s", hdr[i]);
1053 return f;
1056 /* Print, like fprintf, to O. */
1057 void
1058 oprintf (outf_p o, const char *format, ...)
1060 char *s;
1061 size_t slength;
1062 va_list ap;
1064 va_start (ap, format);
1065 slength = xvasprintf (&s, format, ap);
1067 if (o->bufused + slength > o->buflength)
1069 size_t new_len = o->buflength;
1070 if (new_len == 0)
1071 new_len = 1024;
1072 do {
1073 new_len *= 2;
1074 } while (o->bufused + slength >= new_len);
1075 o->buf = XRESIZEVEC (char, o->buf, new_len);
1076 o->buflength = new_len;
1078 memcpy (o->buf + o->bufused, s, slength);
1079 o->bufused += slength;
1080 free (s);
1081 va_end (ap);
1084 /* Open the global header file and the language-specific header files. */
1086 static void
1087 open_base_files (void)
1089 size_t i;
1091 header_file = create_file ("GCC", "gtype-desc.h");
1093 for (i = 0; i < NUM_BASE_FILES; i++)
1094 base_files[i] = create_file (lang_dir_names[i],
1095 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1097 /* gtype-desc.c is a little special, so we create it here. */
1099 /* The order of files here matters very much. */
1100 static const char *const ifiles [] = {
1101 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1102 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1103 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1104 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1105 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1106 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1107 "except.h", "output.h", NULL
1109 const char *const *ifp;
1110 outf_p gtype_desc_c;
1112 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1113 for (ifp = ifiles; *ifp; ifp++)
1114 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1118 /* Determine the pathname to F relative to $(srcdir). */
1120 static const char *
1121 get_file_basename (const char *f)
1123 const char *basename;
1124 unsigned i;
1126 basename = strrchr (f, '/');
1128 if (!basename)
1129 return f;
1131 basename++;
1133 for (i = 1; i < NUM_BASE_FILES; i++)
1135 const char * s1;
1136 const char * s2;
1137 int l1;
1138 int l2;
1139 s1 = basename - strlen (lang_dir_names [i]) - 1;
1140 s2 = lang_dir_names [i];
1141 l1 = strlen (s1);
1142 l2 = strlen (s2);
1143 if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1145 basename -= l2 + 1;
1146 if ((basename - f - 1) != srcdir_len)
1147 fatal ("filename `%s' should be preceded by $srcdir", f);
1148 break;
1152 return basename;
1155 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1156 INPUT_FILE is used by <lang>.
1158 This function should be written to assume that a file _is_ used
1159 if the situation is unclear. If it wrongly assumes a file _is_ used,
1160 a linker error will result. If it wrongly assumes a file _is not_ used,
1161 some GC roots may be missed, which is a much harder-to-debug problem. */
1163 unsigned
1164 get_base_file_bitmap (const char *input_file)
1166 const char *basename = get_file_basename (input_file);
1167 const char *slashpos = strchr (basename, '/');
1168 unsigned j;
1169 unsigned k;
1170 unsigned bitmap;
1172 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1173 it belongs to the corresponding language. The file may belong to other
1174 languages as well (which is checked for below). */
1176 if (slashpos)
1178 size_t i;
1179 for (i = 1; i < NUM_BASE_FILES; i++)
1180 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1181 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1183 /* It's in a language directory, set that language. */
1184 bitmap = 1 << i;
1188 /* If it's in any config-lang.in, then set for the languages
1189 specified. */
1191 bitmap = 0;
1193 for (j = 0; j < NUM_LANG_FILES; j++)
1195 if (!strcmp(input_file, lang_files[j]))
1197 for (k = 0; k < NUM_BASE_FILES; k++)
1199 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1200 bitmap |= (1 << k);
1205 /* Otherwise, set all languages. */
1206 if (!bitmap)
1207 bitmap = (1 << NUM_BASE_FILES) - 1;
1209 return bitmap;
1212 /* An output file, suitable for definitions, that can see declarations
1213 made in INPUT_FILE and is linked into every language that uses
1214 INPUT_FILE. */
1216 outf_p
1217 get_output_file_with_visibility (const char *input_file)
1219 outf_p r;
1220 size_t len;
1221 const char *basename;
1222 const char *for_name;
1223 const char *output_name;
1225 /* This can happen when we need a file with visibility on a
1226 structure that we've never seen. We have to just hope that it's
1227 globally visible. */
1228 if (input_file == NULL)
1229 input_file = "system.h";
1231 /* Determine the output file name. */
1232 basename = get_file_basename (input_file);
1234 len = strlen (basename);
1235 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1236 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1237 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1239 char *s;
1241 output_name = s = xasprintf ("gt-%s", basename);
1242 for (; *s != '.'; s++)
1243 if (! ISALNUM (*s) && *s != '-')
1244 *s = '-';
1245 memcpy (s, ".h", sizeof (".h"));
1246 for_name = basename;
1248 /* Some headers get used by more than one front-end; hence, it
1249 would be inappropriate to spew them out to a single gtype-<lang>.h
1250 (and gengtype doesn't know how to direct spewage into multiple
1251 gtype-<lang>.h headers at this time). Instead, we pair up these
1252 headers with source files (and their special purpose gt-*.h headers). */
1253 else if (strcmp (basename, "c-common.h") == 0)
1254 output_name = "gt-c-common.h", for_name = "c-common.c";
1255 else if (strcmp (basename, "c-tree.h") == 0)
1256 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1257 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1258 && strcmp (basename + 3, "cp-tree.h") == 0)
1259 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1260 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1261 && strcmp (basename + 3, "decl.h") == 0)
1262 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1263 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1264 && strcmp (basename + 3, "name-lookup.h") == 0)
1265 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1266 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1267 && strcmp (basename + 5, "objc-act.h") == 0)
1268 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1269 else
1271 size_t i;
1273 for (i = 0; i < NUM_BASE_FILES; i++)
1274 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1275 && basename[strlen(lang_dir_names[i])] == '/')
1276 return base_files[i];
1278 output_name = "gtype-desc.c";
1279 for_name = NULL;
1282 /* Look through to see if we've ever seen this output filename before. */
1283 for (r = output_files; r; r = r->next)
1284 if (strcmp (r->name, output_name) == 0)
1285 return r;
1287 /* If not, create it. */
1288 r = create_file (for_name, output_name);
1290 return r;
1293 /* The name of an output file, suitable for definitions, that can see
1294 declarations made in INPUT_FILE and is linked into every language
1295 that uses INPUT_FILE. */
1297 const char *
1298 get_output_file_name (const char *input_file)
1300 return get_output_file_with_visibility (input_file)->name;
1303 /* Copy the output to its final destination,
1304 but don't unnecessarily change modification times. */
1306 static void
1307 close_output_files (void)
1309 outf_p of;
1311 for (of = output_files; of; of = of->next)
1313 FILE * newfile;
1315 newfile = fopen (of->name, "r");
1316 if (newfile != NULL )
1318 int no_write_p;
1319 size_t i;
1321 for (i = 0; i < of->bufused; i++)
1323 int ch;
1324 ch = fgetc (newfile);
1325 if (ch == EOF || ch != (unsigned char) of->buf[i])
1326 break;
1328 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1329 fclose (newfile);
1331 if (no_write_p)
1332 continue;
1335 newfile = fopen (of->name, "w");
1336 if (newfile == NULL)
1338 perror ("opening output file");
1339 exit (1);
1341 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1343 perror ("writing output file");
1344 exit (1);
1346 if (fclose (newfile) != 0)
1348 perror ("closing output file");
1349 exit (1);
1354 struct flist {
1355 struct flist *next;
1356 int started_p;
1357 const char *name;
1358 outf_p f;
1361 struct walk_type_data;
1363 /* For scalars and strings, given the item in 'val'.
1364 For structures, given a pointer to the item in 'val'.
1365 For misc. pointers, given the item in 'val'.
1367 typedef void (*process_field_fn)
1368 (type_p f, const struct walk_type_data *p);
1369 typedef void (*func_name_fn)
1370 (type_p s, const struct walk_type_data *p);
1372 /* Parameters for write_types. */
1374 struct write_types_data
1376 const char *prefix;
1377 const char *param_prefix;
1378 const char *subfield_marker_routine;
1379 const char *marker_routine;
1380 const char *reorder_note_routine;
1381 const char *comment;
1384 static void output_escaped_param (struct walk_type_data *d,
1385 const char *, const char *);
1386 static void output_mangled_typename (outf_p, type_p);
1387 static void walk_type (type_p t, struct walk_type_data *d);
1388 static void write_func_for_structure
1389 (type_p orig_s, type_p s, type_p * param,
1390 const struct write_types_data *wtd);
1391 static void write_types_process_field
1392 (type_p f, const struct walk_type_data *d);
1393 static void write_types (type_p structures,
1394 type_p param_structs,
1395 const struct write_types_data *wtd);
1396 static void write_types_local_process_field
1397 (type_p f, const struct walk_type_data *d);
1398 static void write_local_func_for_structure
1399 (type_p orig_s, type_p s, type_p * param);
1400 static void write_local (type_p structures,
1401 type_p param_structs);
1402 static void write_enum_defn (type_p structures, type_p param_structs);
1403 static int contains_scalar_p (type_p t);
1404 static void put_mangled_filename (outf_p , const char *);
1405 static void finish_root_table (struct flist *flp, const char *pfx,
1406 const char *tname, const char *lastname,
1407 const char *name);
1408 static void write_root (outf_p , pair_p, type_p, const char *, int,
1409 struct fileloc *, const char *);
1410 static void write_array (outf_p f, pair_p v,
1411 const struct write_types_data *wtd);
1412 static void write_roots (pair_p);
1414 /* Parameters for walk_type. */
1416 struct walk_type_data
1418 process_field_fn process_field;
1419 const void *cookie;
1420 outf_p of;
1421 options_p opt;
1422 const char *val;
1423 const char *prev_val[4];
1424 int indent;
1425 int counter;
1426 struct fileloc *line;
1427 lang_bitmap bitmap;
1428 type_p *param;
1429 int used_length;
1430 type_p orig_s;
1431 const char *reorder_fn;
1432 bool needs_cast_p;
1433 bool fn_wants_lvalue;
1436 /* Print a mangled name representing T to OF. */
1438 static void
1439 output_mangled_typename (outf_p of, type_p t)
1441 if (t == NULL)
1442 oprintf (of, "Z");
1443 else switch (t->kind)
1445 case TYPE_POINTER:
1446 oprintf (of, "P");
1447 output_mangled_typename (of, t->u.p);
1448 break;
1449 case TYPE_SCALAR:
1450 oprintf (of, "I");
1451 break;
1452 case TYPE_STRING:
1453 oprintf (of, "S");
1454 break;
1455 case TYPE_STRUCT:
1456 case TYPE_UNION:
1457 case TYPE_LANG_STRUCT:
1458 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1459 break;
1460 case TYPE_PARAM_STRUCT:
1462 int i;
1463 for (i = 0; i < NUM_PARAM; i++)
1464 if (t->u.param_struct.param[i] != NULL)
1465 output_mangled_typename (of, t->u.param_struct.param[i]);
1466 output_mangled_typename (of, t->u.param_struct.stru);
1468 break;
1469 case TYPE_ARRAY:
1470 gcc_unreachable ();
1474 /* Print PARAM to D->OF processing escapes. D->VAL references the
1475 current object, D->PREV_VAL the object containing the current
1476 object, ONAME is the name of the option and D->LINE is used to
1477 print error messages. */
1479 static void
1480 output_escaped_param (struct walk_type_data *d, const char *param,
1481 const char *oname)
1483 const char *p;
1485 for (p = param; *p; p++)
1486 if (*p != '%')
1487 oprintf (d->of, "%c", *p);
1488 else switch (*++p)
1490 case 'h':
1491 oprintf (d->of, "(%s)", d->prev_val[2]);
1492 break;
1493 case '0':
1494 oprintf (d->of, "(%s)", d->prev_val[0]);
1495 break;
1496 case '1':
1497 oprintf (d->of, "(%s)", d->prev_val[1]);
1498 break;
1499 case 'a':
1501 const char *pp = d->val + strlen (d->val);
1502 while (pp[-1] == ']')
1503 while (*pp != '[')
1504 pp--;
1505 oprintf (d->of, "%s", pp);
1507 break;
1508 default:
1509 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1510 oname, '%', *p);
1514 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1515 which is of type T. Write code to D->OF to constrain execution (at
1516 the point that D->PROCESS_FIELD is called) to the appropriate
1517 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1518 pointers to those objects. D->PREV_VAL lists the objects
1519 containing the current object, D->OPT is a list of options to
1520 apply, D->INDENT is the current indentation level, D->LINE is used
1521 to print error messages, D->BITMAP indicates which languages to
1522 print the structure for, and D->PARAM is the current parameter
1523 (from an enclosing param_is option). */
1525 static void
1526 walk_type (type_p t, struct walk_type_data *d)
1528 const char *length = NULL;
1529 const char *desc = NULL;
1530 int maybe_undef_p = 0;
1531 int use_param_num = -1;
1532 int use_params_p = 0;
1533 options_p oo;
1534 const struct nested_ptr_data *nested_ptr_d = NULL;
1536 d->needs_cast_p = false;
1537 for (oo = d->opt; oo; oo = oo->next)
1538 if (strcmp (oo->name, "length") == 0)
1539 length = oo->info;
1540 else if (strcmp (oo->name, "maybe_undef") == 0)
1541 maybe_undef_p = 1;
1542 else if (strncmp (oo->name, "use_param", 9) == 0
1543 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1544 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1545 else if (strcmp (oo->name, "use_params") == 0)
1546 use_params_p = 1;
1547 else if (strcmp (oo->name, "desc") == 0)
1548 desc = oo->info;
1549 else if (strcmp (oo->name, "nested_ptr") == 0)
1550 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1551 else if (strcmp (oo->name, "dot") == 0)
1553 else if (strcmp (oo->name, "tag") == 0)
1555 else if (strcmp (oo->name, "special") == 0)
1557 else if (strcmp (oo->name, "skip") == 0)
1559 else if (strcmp (oo->name, "default") == 0)
1561 else if (strcmp (oo->name, "descbits") == 0)
1563 else if (strcmp (oo->name, "param_is") == 0)
1565 else if (strncmp (oo->name, "param", 5) == 0
1566 && ISDIGIT (oo->name[5])
1567 && strcmp (oo->name + 6, "_is") == 0)
1569 else if (strcmp (oo->name, "chain_next") == 0)
1571 else if (strcmp (oo->name, "chain_prev") == 0)
1573 else if (strcmp (oo->name, "reorder") == 0)
1575 else
1576 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1578 if (d->used_length)
1579 length = NULL;
1581 if (use_params_p)
1583 int pointer_p = t->kind == TYPE_POINTER;
1585 if (pointer_p)
1586 t = t->u.p;
1587 if (! UNION_OR_STRUCT_P (t))
1588 error_at_line (d->line, "`use_params' option on unimplemented type");
1589 else
1590 t = find_param_structure (t, d->param);
1591 if (pointer_p)
1592 t = create_pointer (t);
1595 if (use_param_num != -1)
1597 if (d->param != NULL && d->param[use_param_num] != NULL)
1599 type_p nt = d->param[use_param_num];
1601 if (t->kind == TYPE_ARRAY)
1602 nt = create_array (nt, t->u.a.len);
1603 else if (length != NULL && t->kind == TYPE_POINTER)
1604 nt = create_pointer (nt);
1605 d->needs_cast_p = (t->kind != TYPE_POINTER
1606 && (nt->kind == TYPE_POINTER
1607 || nt->kind == TYPE_STRING));
1608 t = nt;
1610 else
1611 error_at_line (d->line, "no parameter defined for `%s'",
1612 d->val);
1615 if (maybe_undef_p
1616 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1618 error_at_line (d->line,
1619 "field `%s' has invalid option `maybe_undef_p'\n",
1620 d->val);
1621 return;
1624 switch (t->kind)
1626 case TYPE_SCALAR:
1627 case TYPE_STRING:
1628 d->process_field (t, d);
1629 break;
1631 case TYPE_POINTER:
1633 if (maybe_undef_p
1634 && t->u.p->u.s.line.file == NULL)
1636 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1637 break;
1640 if (! length)
1642 if (! UNION_OR_STRUCT_P (t->u.p)
1643 && t->u.p->kind != TYPE_PARAM_STRUCT)
1645 error_at_line (d->line,
1646 "field `%s' is pointer to unimplemented type",
1647 d->val);
1648 break;
1651 if (nested_ptr_d)
1653 const char *oldprevval2 = d->prev_val[2];
1655 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1657 error_at_line (d->line,
1658 "field `%s' has invalid "
1659 "option `nested_ptr'\n",
1660 d->val);
1661 return;
1664 d->prev_val[2] = d->val;
1665 oprintf (d->of, "%*s{\n", d->indent, "");
1666 d->indent += 2;
1667 d->val = xasprintf ("x%d", d->counter++);
1668 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1669 (nested_ptr_d->type->kind == TYPE_UNION
1670 ? "union" : "struct"),
1671 nested_ptr_d->type->u.s.tag,
1672 d->fn_wants_lvalue ? "" : "const ",
1673 d->val);
1674 oprintf (d->of, "%*s", d->indent + 2, "");
1675 output_escaped_param (d, nested_ptr_d->convert_from,
1676 "nested_ptr");
1677 oprintf (d->of, ";\n");
1679 d->process_field (nested_ptr_d->type, d);
1681 if (d->fn_wants_lvalue)
1683 oprintf (d->of, "%*s%s = ", d->indent, "",
1684 d->prev_val[2]);
1685 d->prev_val[2] = d->val;
1686 output_escaped_param (d, nested_ptr_d->convert_to,
1687 "nested_ptr");
1688 oprintf (d->of, ";\n");
1691 d->indent -= 2;
1692 oprintf (d->of, "%*s}\n", d->indent, "");
1693 d->val = d->prev_val[2];
1694 d->prev_val[2] = oldprevval2;
1696 else
1697 d->process_field (t->u.p, d);
1699 else
1701 int loopcounter = d->counter++;
1702 const char *oldval = d->val;
1703 const char *oldprevval3 = d->prev_val[3];
1704 char *newval;
1706 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1707 d->indent += 2;
1708 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1709 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1710 loopcounter, loopcounter);
1711 output_escaped_param (d, length, "length");
1712 oprintf (d->of, "); i%d++) {\n", loopcounter);
1713 d->indent += 2;
1714 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1715 d->used_length = 1;
1716 d->prev_val[3] = oldval;
1717 walk_type (t->u.p, d);
1718 free (newval);
1719 d->val = oldval;
1720 d->prev_val[3] = oldprevval3;
1721 d->used_length = 0;
1722 d->indent -= 2;
1723 oprintf (d->of, "%*s}\n", d->indent, "");
1724 d->process_field(t, d);
1725 d->indent -= 2;
1726 oprintf (d->of, "%*s}\n", d->indent, "");
1729 break;
1731 case TYPE_ARRAY:
1733 int loopcounter = d->counter++;
1734 const char *oldval = d->val;
1735 char *newval;
1737 /* If it's an array of scalars, we optimize by not generating
1738 any code. */
1739 if (t->u.a.p->kind == TYPE_SCALAR)
1740 break;
1742 oprintf (d->of, "%*s{\n", d->indent, "");
1743 d->indent += 2;
1744 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1745 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1746 loopcounter, loopcounter);
1747 if (length)
1748 output_escaped_param (d, length, "length");
1749 else
1750 oprintf (d->of, "%s", t->u.a.len);
1751 oprintf (d->of, "); i%d++) {\n", loopcounter);
1752 d->indent += 2;
1753 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1754 d->used_length = 1;
1755 walk_type (t->u.a.p, d);
1756 free (newval);
1757 d->used_length = 0;
1758 d->val = oldval;
1759 d->indent -= 2;
1760 oprintf (d->of, "%*s}\n", d->indent, "");
1761 d->indent -= 2;
1762 oprintf (d->of, "%*s}\n", d->indent, "");
1764 break;
1766 case TYPE_STRUCT:
1767 case TYPE_UNION:
1769 pair_p f;
1770 const char *oldval = d->val;
1771 const char *oldprevval1 = d->prev_val[1];
1772 const char *oldprevval2 = d->prev_val[2];
1773 const int union_p = t->kind == TYPE_UNION;
1774 int seen_default_p = 0;
1775 options_p o;
1777 if (! t->u.s.line.file)
1778 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1780 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1782 error_at_line (d->line,
1783 "structure `%s' defined for mismatching languages",
1784 t->u.s.tag);
1785 error_at_line (&t->u.s.line, "one structure defined here");
1788 /* Some things may also be defined in the structure's options. */
1789 for (o = t->u.s.opt; o; o = o->next)
1790 if (! desc && strcmp (o->name, "desc") == 0)
1791 desc = o->info;
1793 d->prev_val[2] = oldval;
1794 d->prev_val[1] = oldprevval2;
1795 if (union_p)
1797 if (desc == NULL)
1799 error_at_line (d->line, "missing `desc' option for union `%s'",
1800 t->u.s.tag);
1801 desc = "1";
1803 oprintf (d->of, "%*sswitch (", d->indent, "");
1804 output_escaped_param (d, desc, "desc");
1805 oprintf (d->of, ")\n");
1806 d->indent += 2;
1807 oprintf (d->of, "%*s{\n", d->indent, "");
1809 for (f = t->u.s.fields; f; f = f->next)
1811 options_p oo;
1812 const char *dot = ".";
1813 const char *tagid = NULL;
1814 int skip_p = 0;
1815 int default_p = 0;
1816 int use_param_p = 0;
1817 char *newval;
1819 d->reorder_fn = NULL;
1820 for (oo = f->opt; oo; oo = oo->next)
1821 if (strcmp (oo->name, "dot") == 0)
1822 dot = oo->info;
1823 else if (strcmp (oo->name, "tag") == 0)
1824 tagid = oo->info;
1825 else if (strcmp (oo->name, "skip") == 0)
1826 skip_p = 1;
1827 else if (strcmp (oo->name, "default") == 0)
1828 default_p = 1;
1829 else if (strcmp (oo->name, "reorder") == 0)
1830 d->reorder_fn = oo->info;
1831 else if (strncmp (oo->name, "use_param", 9) == 0
1832 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1833 use_param_p = 1;
1835 if (skip_p)
1836 continue;
1838 if (union_p && tagid)
1840 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1841 d->indent += 2;
1843 else if (union_p && default_p)
1845 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1846 d->indent += 2;
1847 seen_default_p = 1;
1849 else if (! union_p && (default_p || tagid))
1850 error_at_line (d->line,
1851 "can't use `%s' outside a union on field `%s'",
1852 default_p ? "default" : "tag", f->name);
1853 else if (union_p && ! (default_p || tagid)
1854 && f->type->kind == TYPE_SCALAR)
1856 fprintf (stderr,
1857 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1858 d->line->file, d->line->line, f->name);
1859 continue;
1861 else if (union_p && ! (default_p || tagid))
1862 error_at_line (d->line,
1863 "field `%s' is missing `tag' or `default' option",
1864 f->name);
1866 d->line = &f->line;
1867 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1868 d->opt = f->opt;
1869 d->used_length = false;
1871 if (union_p && use_param_p && d->param == NULL)
1872 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1873 else
1874 walk_type (f->type, d);
1876 free (newval);
1878 if (union_p)
1880 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1881 d->indent -= 2;
1884 d->reorder_fn = NULL;
1886 d->val = oldval;
1887 d->prev_val[1] = oldprevval1;
1888 d->prev_val[2] = oldprevval2;
1890 if (union_p && ! seen_default_p)
1892 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1893 oprintf (d->of, "%*s break;\n", d->indent, "");
1895 if (union_p)
1897 oprintf (d->of, "%*s}\n", d->indent, "");
1898 d->indent -= 2;
1901 break;
1903 case TYPE_LANG_STRUCT:
1905 type_p nt;
1906 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1907 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1908 break;
1909 if (nt == NULL)
1910 error_at_line (d->line, "structure `%s' differs between languages",
1911 t->u.s.tag);
1912 else
1913 walk_type (nt, d);
1915 break;
1917 case TYPE_PARAM_STRUCT:
1919 type_p *oldparam = d->param;
1921 d->param = t->u.param_struct.param;
1922 walk_type (t->u.param_struct.stru, d);
1923 d->param = oldparam;
1925 break;
1927 default:
1928 gcc_unreachable ();
1932 /* process_field routine for marking routines. */
1934 static void
1935 write_types_process_field (type_p f, const struct walk_type_data *d)
1937 const struct write_types_data *wtd;
1938 const char *cast = d->needs_cast_p ? "(void *)" : "";
1939 wtd = (const struct write_types_data *) d->cookie;
1941 switch (f->kind)
1943 case TYPE_POINTER:
1944 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1945 wtd->subfield_marker_routine, cast, d->val);
1946 if (wtd->param_prefix)
1948 oprintf (d->of, ", %s", d->prev_val[3]);
1949 if (d->orig_s)
1951 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1952 output_mangled_typename (d->of, d->orig_s);
1954 else
1955 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1957 if (f->u.p->kind == TYPE_PARAM_STRUCT
1958 && f->u.p->u.s.line.file != NULL)
1960 oprintf (d->of, ", gt_e_");
1961 output_mangled_typename (d->of, f);
1963 else if (UNION_OR_STRUCT_P (f)
1964 && f->u.p->u.s.line.file != NULL)
1966 oprintf (d->of, ", gt_ggc_e_");
1967 output_mangled_typename (d->of, f);
1969 else
1970 oprintf (d->of, ", gt_types_enum_last");
1972 oprintf (d->of, ");\n");
1973 if (d->reorder_fn && wtd->reorder_note_routine)
1974 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1975 wtd->reorder_note_routine, cast, d->val,
1976 d->prev_val[3], d->reorder_fn);
1977 break;
1979 case TYPE_STRING:
1980 if (wtd->param_prefix == NULL)
1981 break;
1983 case TYPE_STRUCT:
1984 case TYPE_UNION:
1985 case TYPE_LANG_STRUCT:
1986 case TYPE_PARAM_STRUCT:
1987 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1988 output_mangled_typename (d->of, f);
1989 oprintf (d->of, " (%s%s);\n", cast, d->val);
1990 if (d->reorder_fn && wtd->reorder_note_routine)
1991 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1992 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1993 d->reorder_fn);
1994 break;
1996 case TYPE_SCALAR:
1997 break;
1999 default:
2000 gcc_unreachable ();
2004 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
2006 static void
2007 output_type_enum (outf_p of, type_p s)
2009 if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2011 oprintf (of, ", gt_e_");
2012 output_mangled_typename (of, s);
2014 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2016 oprintf (of, ", gt_ggc_e_");
2017 output_mangled_typename (of, s);
2019 else
2020 oprintf (of, ", gt_types_enum_last");
2023 /* For S, a structure that's part of ORIG_S, and using parameters
2024 PARAM, write out a routine that:
2025 - Takes a parameter, a void * but actually of type *S
2026 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2027 field of S or its substructures and (in some cases) things
2028 that are pointed to by S.
2031 static void
2032 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2033 const struct write_types_data *wtd)
2035 const char *fn = s->u.s.line.file;
2036 int i;
2037 const char *chain_next = NULL;
2038 const char *chain_prev = NULL;
2039 options_p opt;
2040 struct walk_type_data d;
2042 /* This is a hack, and not the good kind either. */
2043 for (i = NUM_PARAM - 1; i >= 0; i--)
2044 if (param && param[i] && param[i]->kind == TYPE_POINTER
2045 && UNION_OR_STRUCT_P (param[i]->u.p))
2046 fn = param[i]->u.p->u.s.line.file;
2048 memset (&d, 0, sizeof (d));
2049 d.of = get_output_file_with_visibility (fn);
2051 for (opt = s->u.s.opt; opt; opt = opt->next)
2052 if (strcmp (opt->name, "chain_next") == 0)
2053 chain_next = opt->info;
2054 else if (strcmp (opt->name, "chain_prev") == 0)
2055 chain_prev = opt->info;
2057 if (chain_prev != NULL && chain_next == NULL)
2058 error_at_line (&s->u.s.line, "chain_prev without chain_next");
2060 d.process_field = write_types_process_field;
2061 d.cookie = wtd;
2062 d.orig_s = orig_s;
2063 d.opt = s->u.s.opt;
2064 d.line = &s->u.s.line;
2065 d.bitmap = s->u.s.bitmap;
2066 d.param = param;
2067 d.prev_val[0] = "*x";
2068 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2069 d.prev_val[3] = "x";
2070 d.val = "(*x)";
2072 oprintf (d.of, "\n");
2073 oprintf (d.of, "void\n");
2074 if (param == NULL)
2075 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2076 else
2078 oprintf (d.of, "gt_%s_", wtd->prefix);
2079 output_mangled_typename (d.of, orig_s);
2081 oprintf (d.of, " (void *x_p)\n");
2082 oprintf (d.of, "{\n");
2083 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2084 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2085 chain_next == NULL ? "const " : "",
2086 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2087 if (chain_next != NULL)
2088 oprintf (d.of, " %s %s * xlimit = x;\n",
2089 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2090 if (chain_next == NULL)
2092 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2093 if (wtd->param_prefix)
2095 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2096 output_mangled_typename (d.of, orig_s);
2097 output_type_enum (d.of, orig_s);
2099 oprintf (d.of, "))\n");
2101 else
2103 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2104 if (wtd->param_prefix)
2106 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2107 output_mangled_typename (d.of, orig_s);
2108 output_type_enum (d.of, orig_s);
2110 oprintf (d.of, "))\n");
2111 oprintf (d.of, " xlimit = (");
2112 d.prev_val[2] = "*xlimit";
2113 output_escaped_param (&d, chain_next, "chain_next");
2114 oprintf (d.of, ");\n");
2115 if (chain_prev != NULL)
2117 oprintf (d.of, " if (x != xlimit)\n");
2118 oprintf (d.of, " for (;;)\n");
2119 oprintf (d.of, " {\n");
2120 oprintf (d.of, " %s %s * const xprev = (",
2121 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2123 d.prev_val[2] = "*x";
2124 output_escaped_param (&d, chain_prev, "chain_prev");
2125 oprintf (d.of, ");\n");
2126 oprintf (d.of, " if (xprev == NULL) break;\n");
2127 oprintf (d.of, " x = xprev;\n");
2128 oprintf (d.of, " (void) %s (xprev",
2129 wtd->marker_routine);
2130 if (wtd->param_prefix)
2132 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2133 output_mangled_typename (d.of, orig_s);
2134 output_type_enum (d.of, orig_s);
2136 oprintf (d.of, ");\n");
2137 oprintf (d.of, " }\n");
2139 oprintf (d.of, " while (x != xlimit)\n");
2141 oprintf (d.of, " {\n");
2143 d.prev_val[2] = "*x";
2144 d.indent = 6;
2145 walk_type (s, &d);
2147 if (chain_next != NULL)
2149 oprintf (d.of, " x = (");
2150 output_escaped_param (&d, chain_next, "chain_next");
2151 oprintf (d.of, ");\n");
2154 oprintf (d.of, " }\n");
2155 oprintf (d.of, "}\n");
2158 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2160 static void
2161 write_types (type_p structures, type_p param_structs,
2162 const struct write_types_data *wtd)
2164 type_p s;
2166 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2167 for (s = structures; s; s = s->next)
2168 if (s->gc_used == GC_POINTED_TO
2169 || s->gc_used == GC_MAYBE_POINTED_TO)
2171 options_p opt;
2173 if (s->gc_used == GC_MAYBE_POINTED_TO
2174 && s->u.s.line.file == NULL)
2175 continue;
2177 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2178 output_mangled_typename (header_file, s);
2179 oprintf (header_file, "(X) do { \\\n");
2180 oprintf (header_file,
2181 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2182 s->u.s.tag);
2183 oprintf (header_file,
2184 " } while (0)\n");
2186 for (opt = s->u.s.opt; opt; opt = opt->next)
2187 if (strcmp (opt->name, "ptr_alias") == 0)
2189 type_p t = (type_p) opt->info;
2190 if (t->kind == TYPE_STRUCT
2191 || t->kind == TYPE_UNION
2192 || t->kind == TYPE_LANG_STRUCT)
2193 oprintf (header_file,
2194 "#define gt_%sx_%s gt_%sx_%s\n",
2195 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2196 else
2197 error_at_line (&s->u.s.line,
2198 "structure alias is not a structure");
2199 break;
2201 if (opt)
2202 continue;
2204 /* Declare the marker procedure only once. */
2205 oprintf (header_file,
2206 "extern void gt_%sx_%s (void *);\n",
2207 wtd->prefix, s->u.s.tag);
2209 if (s->u.s.line.file == NULL)
2211 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2212 s->u.s.tag);
2213 continue;
2216 if (s->kind == TYPE_LANG_STRUCT)
2218 type_p ss;
2219 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2220 write_func_for_structure (s, ss, NULL, wtd);
2222 else
2223 write_func_for_structure (s, s, NULL, wtd);
2226 for (s = param_structs; s; s = s->next)
2227 if (s->gc_used == GC_POINTED_TO)
2229 type_p * param = s->u.param_struct.param;
2230 type_p stru = s->u.param_struct.stru;
2232 /* Declare the marker procedure. */
2233 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2234 output_mangled_typename (header_file, s);
2235 oprintf (header_file, " (void *);\n");
2237 if (stru->u.s.line.file == NULL)
2239 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2240 s->u.s.tag);
2241 continue;
2244 if (stru->kind == TYPE_LANG_STRUCT)
2246 type_p ss;
2247 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2248 write_func_for_structure (s, ss, param, wtd);
2250 else
2251 write_func_for_structure (s, stru, param, wtd);
2255 static const struct write_types_data ggc_wtd =
2257 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2258 "GC marker procedures. "
2261 static const struct write_types_data pch_wtd =
2263 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2264 "gt_pch_note_reorder",
2265 "PCH type-walking procedures. "
2268 /* Write out the local pointer-walking routines. */
2270 /* process_field routine for local pointer-walking. */
2272 static void
2273 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2275 switch (f->kind)
2277 case TYPE_POINTER:
2278 case TYPE_STRUCT:
2279 case TYPE_UNION:
2280 case TYPE_LANG_STRUCT:
2281 case TYPE_PARAM_STRUCT:
2282 case TYPE_STRING:
2283 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2284 d->prev_val[3]);
2285 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2286 break;
2288 case TYPE_SCALAR:
2289 break;
2291 default:
2292 gcc_unreachable ();
2296 /* For S, a structure that's part of ORIG_S, and using parameters
2297 PARAM, write out a routine that:
2298 - Is of type gt_note_pointers
2299 - Calls PROCESS_FIELD on each field of S or its substructures.
2302 static void
2303 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2305 const char *fn = s->u.s.line.file;
2306 int i;
2307 struct walk_type_data d;
2309 /* This is a hack, and not the good kind either. */
2310 for (i = NUM_PARAM - 1; i >= 0; i--)
2311 if (param && param[i] && param[i]->kind == TYPE_POINTER
2312 && UNION_OR_STRUCT_P (param[i]->u.p))
2313 fn = param[i]->u.p->u.s.line.file;
2315 memset (&d, 0, sizeof (d));
2316 d.of = get_output_file_with_visibility (fn);
2318 d.process_field = write_types_local_process_field;
2319 d.opt = s->u.s.opt;
2320 d.line = &s->u.s.line;
2321 d.bitmap = s->u.s.bitmap;
2322 d.param = param;
2323 d.prev_val[0] = d.prev_val[2] = "*x";
2324 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2325 d.prev_val[3] = "x";
2326 d.val = "(*x)";
2327 d.fn_wants_lvalue = true;
2329 oprintf (d.of, "\n");
2330 oprintf (d.of, "void\n");
2331 oprintf (d.of, "gt_pch_p_");
2332 output_mangled_typename (d.of, orig_s);
2333 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2334 "\tvoid *x_p,\n"
2335 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2336 "\tATTRIBUTE_UNUSED void *cookie)\n");
2337 oprintf (d.of, "{\n");
2338 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2339 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2340 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2341 d.indent = 2;
2342 walk_type (s, &d);
2343 oprintf (d.of, "}\n");
2346 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2348 static void
2349 write_local (type_p structures, type_p param_structs)
2351 type_p s;
2353 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2354 for (s = structures; s; s = s->next)
2355 if (s->gc_used == GC_POINTED_TO
2356 || s->gc_used == GC_MAYBE_POINTED_TO)
2358 options_p opt;
2360 if (s->u.s.line.file == NULL)
2361 continue;
2363 for (opt = s->u.s.opt; opt; opt = opt->next)
2364 if (strcmp (opt->name, "ptr_alias") == 0)
2366 type_p t = (type_p) opt->info;
2367 if (t->kind == TYPE_STRUCT
2368 || t->kind == TYPE_UNION
2369 || t->kind == TYPE_LANG_STRUCT)
2371 oprintf (header_file, "#define gt_pch_p_");
2372 output_mangled_typename (header_file, s);
2373 oprintf (header_file, " gt_pch_p_");
2374 output_mangled_typename (header_file, t);
2375 oprintf (header_file, "\n");
2377 else
2378 error_at_line (&s->u.s.line,
2379 "structure alias is not a structure");
2380 break;
2382 if (opt)
2383 continue;
2385 /* Declare the marker procedure only once. */
2386 oprintf (header_file, "extern void gt_pch_p_");
2387 output_mangled_typename (header_file, s);
2388 oprintf (header_file,
2389 "\n (void *, void *, gt_pointer_operator, void *);\n");
2391 if (s->kind == TYPE_LANG_STRUCT)
2393 type_p ss;
2394 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2395 write_local_func_for_structure (s, ss, NULL);
2397 else
2398 write_local_func_for_structure (s, s, NULL);
2401 for (s = param_structs; s; s = s->next)
2402 if (s->gc_used == GC_POINTED_TO)
2404 type_p * param = s->u.param_struct.param;
2405 type_p stru = s->u.param_struct.stru;
2407 /* Declare the marker procedure. */
2408 oprintf (header_file, "extern void gt_pch_p_");
2409 output_mangled_typename (header_file, s);
2410 oprintf (header_file,
2411 "\n (void *, void *, gt_pointer_operator, void *);\n");
2413 if (stru->u.s.line.file == NULL)
2415 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2416 s->u.s.tag);
2417 continue;
2420 if (stru->kind == TYPE_LANG_STRUCT)
2422 type_p ss;
2423 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2424 write_local_func_for_structure (s, ss, param);
2426 else
2427 write_local_func_for_structure (s, stru, param);
2431 /* Write out the 'enum' definition for gt_types_enum. */
2433 static void
2434 write_enum_defn (type_p structures, type_p param_structs)
2436 type_p s;
2438 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2439 oprintf (header_file, "enum gt_types_enum {\n");
2440 for (s = structures; s; s = s->next)
2441 if (s->gc_used == GC_POINTED_TO
2442 || s->gc_used == GC_MAYBE_POINTED_TO)
2444 if (s->gc_used == GC_MAYBE_POINTED_TO
2445 && s->u.s.line.file == NULL)
2446 continue;
2448 oprintf (header_file, " gt_ggc_e_");
2449 output_mangled_typename (header_file, s);
2450 oprintf (header_file, ", \n");
2452 for (s = param_structs; s; s = s->next)
2453 if (s->gc_used == GC_POINTED_TO)
2455 oprintf (header_file, " gt_e_");
2456 output_mangled_typename (header_file, s);
2457 oprintf (header_file, ", \n");
2459 oprintf (header_file, " gt_types_enum_last\n");
2460 oprintf (header_file, "};\n");
2463 /* Might T contain any non-pointer elements? */
2465 static int
2466 contains_scalar_p (type_p t)
2468 switch (t->kind)
2470 case TYPE_STRING:
2471 case TYPE_POINTER:
2472 return 0;
2473 case TYPE_ARRAY:
2474 return contains_scalar_p (t->u.a.p);
2475 default:
2476 /* Could also check for structures that have no non-pointer
2477 fields, but there aren't enough of those to worry about. */
2478 return 1;
2482 /* Mangle FN and print it to F. */
2484 static void
2485 put_mangled_filename (outf_p f, const char *fn)
2487 const char *name = get_output_file_name (fn);
2488 for (; *name != 0; name++)
2489 if (ISALNUM (*name))
2490 oprintf (f, "%c", *name);
2491 else
2492 oprintf (f, "%c", '_');
2495 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2496 LASTNAME, and NAME are all strings to insert in various places in
2497 the resulting code. */
2499 static void
2500 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2501 const char *tname, const char *name)
2503 struct flist *fli2;
2505 for (fli2 = flp; fli2; fli2 = fli2->next)
2506 if (fli2->started_p)
2508 oprintf (fli2->f, " %s\n", lastname);
2509 oprintf (fli2->f, "};\n\n");
2512 for (fli2 = flp; fli2; fli2 = fli2->next)
2513 if (fli2->started_p)
2515 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2516 int fnum;
2518 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2519 if (bitmap & 1)
2521 oprintf (base_files[fnum],
2522 "extern const struct %s gt_%s_",
2523 tname, pfx);
2524 put_mangled_filename (base_files[fnum], fli2->name);
2525 oprintf (base_files[fnum], "[];\n");
2530 size_t fnum;
2531 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2532 oprintf (base_files [fnum],
2533 "const struct %s * const %s[] = {\n",
2534 tname, name);
2538 for (fli2 = flp; fli2; fli2 = fli2->next)
2539 if (fli2->started_p)
2541 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2542 int fnum;
2544 fli2->started_p = 0;
2546 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2547 if (bitmap & 1)
2549 oprintf (base_files[fnum], " gt_%s_", pfx);
2550 put_mangled_filename (base_files[fnum], fli2->name);
2551 oprintf (base_files[fnum], ",\n");
2556 size_t fnum;
2557 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2559 oprintf (base_files[fnum], " NULL\n");
2560 oprintf (base_files[fnum], "};\n");
2565 /* Write out to F the table entry and any marker routines needed to
2566 mark NAME as TYPE. The original variable is V, at LINE.
2567 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2568 is nonzero iff we are building the root table for hash table caches. */
2570 static void
2571 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2572 struct fileloc *line, const char *if_marked)
2574 switch (type->kind)
2576 case TYPE_STRUCT:
2578 pair_p fld;
2579 for (fld = type->u.s.fields; fld; fld = fld->next)
2581 int skip_p = 0;
2582 const char *desc = NULL;
2583 options_p o;
2585 for (o = fld->opt; o; o = o->next)
2586 if (strcmp (o->name, "skip") == 0)
2587 skip_p = 1;
2588 else if (strcmp (o->name, "desc") == 0)
2589 desc = o->info;
2590 else
2591 error_at_line (line,
2592 "field `%s' of global `%s' has unknown option `%s'",
2593 fld->name, name, o->name);
2595 if (skip_p)
2596 continue;
2597 else if (desc && fld->type->kind == TYPE_UNION)
2599 pair_p validf = NULL;
2600 pair_p ufld;
2602 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2604 const char *tag = NULL;
2605 options_p oo;
2607 for (oo = ufld->opt; oo; oo = oo->next)
2608 if (strcmp (oo->name, "tag") == 0)
2609 tag = oo->info;
2610 if (tag == NULL || strcmp (tag, desc) != 0)
2611 continue;
2612 if (validf != NULL)
2613 error_at_line (line,
2614 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2615 name, fld->name, validf->name,
2616 name, fld->name, ufld->name,
2617 tag);
2618 validf = ufld;
2620 if (validf != NULL)
2622 char *newname;
2623 newname = xasprintf ("%s.%s.%s",
2624 name, fld->name, validf->name);
2625 write_root (f, v, validf->type, newname, 0, line,
2626 if_marked);
2627 free (newname);
2630 else if (desc)
2631 error_at_line (line,
2632 "global `%s.%s' has `desc' option but is not union",
2633 name, fld->name);
2634 else
2636 char *newname;
2637 newname = xasprintf ("%s.%s", name, fld->name);
2638 write_root (f, v, fld->type, newname, 0, line, if_marked);
2639 free (newname);
2643 break;
2645 case TYPE_ARRAY:
2647 char *newname;
2648 newname = xasprintf ("%s[0]", name);
2649 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2650 free (newname);
2652 break;
2654 case TYPE_POINTER:
2656 type_p ap, tp;
2658 oprintf (f, " {\n");
2659 oprintf (f, " &%s,\n", name);
2660 oprintf (f, " 1");
2662 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2663 if (ap->u.a.len[0])
2664 oprintf (f, " * (%s)", ap->u.a.len);
2665 else if (ap == v->type)
2666 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2667 oprintf (f, ",\n");
2668 oprintf (f, " sizeof (%s", v->name);
2669 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2670 oprintf (f, "[0]");
2671 oprintf (f, "),\n");
2673 tp = type->u.p;
2675 if (! has_length && UNION_OR_STRUCT_P (tp))
2677 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2678 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2680 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2682 oprintf (f, " &gt_ggc_m_");
2683 output_mangled_typename (f, tp);
2684 oprintf (f, ",\n &gt_pch_n_");
2685 output_mangled_typename (f, tp);
2687 else if (has_length
2688 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2690 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2691 oprintf (f, " &gt_pch_na_%s", name);
2693 else
2695 error_at_line (line,
2696 "global `%s' is pointer to unimplemented type",
2697 name);
2699 if (if_marked)
2700 oprintf (f, ",\n &%s", if_marked);
2701 oprintf (f, "\n },\n");
2703 break;
2705 case TYPE_STRING:
2707 oprintf (f, " {\n");
2708 oprintf (f, " &%s,\n", name);
2709 oprintf (f, " 1, \n");
2710 oprintf (f, " sizeof (%s),\n", v->name);
2711 oprintf (f, " &gt_ggc_m_S,\n");
2712 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2713 oprintf (f, " },\n");
2715 break;
2717 case TYPE_SCALAR:
2718 break;
2720 default:
2721 error_at_line (line,
2722 "global `%s' is unimplemented type",
2723 name);
2727 /* This generates a routine to walk an array. */
2729 static void
2730 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2732 struct walk_type_data d;
2733 char *prevval3;
2735 memset (&d, 0, sizeof (d));
2736 d.of = f;
2737 d.cookie = wtd;
2738 d.indent = 2;
2739 d.line = &v->line;
2740 d.opt = v->opt;
2741 d.bitmap = get_base_file_bitmap (v->line.file);
2742 d.param = NULL;
2744 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2746 if (wtd->param_prefix)
2748 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2749 oprintf (f,
2750 " (void *, void *, gt_pointer_operator, void *);\n");
2751 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2752 wtd->param_prefix, v->name);
2753 oprintf (d.of,
2754 " ATTRIBUTE_UNUSED void *x_p,\n"
2755 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2756 " ATTRIBUTE_UNUSED void * cookie)\n");
2757 oprintf (d.of, "{\n");
2758 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2759 d.process_field = write_types_local_process_field;
2760 walk_type (v->type, &d);
2761 oprintf (f, "}\n\n");
2764 d.opt = v->opt;
2765 oprintf (f, "static void gt_%sa_%s (void *);\n",
2766 wtd->prefix, v->name);
2767 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2768 wtd->prefix, v->name);
2769 oprintf (f, "{\n");
2770 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2771 d.process_field = write_types_process_field;
2772 walk_type (v->type, &d);
2773 free (prevval3);
2774 oprintf (f, "}\n\n");
2777 /* Output a table describing the locations and types of VARIABLES. */
2779 static void
2780 write_roots (pair_p variables)
2782 pair_p v;
2783 struct flist *flp = NULL;
2785 for (v = variables; v; v = v->next)
2787 outf_p f = get_output_file_with_visibility (v->line.file);
2788 struct flist *fli;
2789 const char *length = NULL;
2790 int deletable_p = 0;
2791 options_p o;
2793 for (o = v->opt; o; o = o->next)
2794 if (strcmp (o->name, "length") == 0)
2795 length = o->info;
2796 else if (strcmp (o->name, "deletable") == 0)
2797 deletable_p = 1;
2798 else if (strcmp (o->name, "param_is") == 0)
2800 else if (strncmp (o->name, "param", 5) == 0
2801 && ISDIGIT (o->name[5])
2802 && strcmp (o->name + 6, "_is") == 0)
2804 else if (strcmp (o->name, "if_marked") == 0)
2806 else
2807 error_at_line (&v->line,
2808 "global `%s' has unknown option `%s'",
2809 v->name, o->name);
2811 for (fli = flp; fli; fli = fli->next)
2812 if (fli->f == f)
2813 break;
2814 if (fli == NULL)
2816 fli = XNEW (struct flist);
2817 fli->f = f;
2818 fli->next = flp;
2819 fli->started_p = 0;
2820 fli->name = v->line.file;
2821 flp = fli;
2823 oprintf (f, "\n/* GC roots. */\n\n");
2826 if (! deletable_p
2827 && length
2828 && v->type->kind == TYPE_POINTER
2829 && (v->type->u.p->kind == TYPE_POINTER
2830 || v->type->u.p->kind == TYPE_STRUCT))
2832 write_array (f, v, &ggc_wtd);
2833 write_array (f, v, &pch_wtd);
2837 for (v = variables; v; v = v->next)
2839 outf_p f = get_output_file_with_visibility (v->line.file);
2840 struct flist *fli;
2841 int skip_p = 0;
2842 int length_p = 0;
2843 options_p o;
2845 for (o = v->opt; o; o = o->next)
2846 if (strcmp (o->name, "length") == 0)
2847 length_p = 1;
2848 else if (strcmp (o->name, "deletable") == 0
2849 || strcmp (o->name, "if_marked") == 0)
2850 skip_p = 1;
2852 if (skip_p)
2853 continue;
2855 for (fli = flp; fli; fli = fli->next)
2856 if (fli->f == f)
2857 break;
2858 if (! fli->started_p)
2860 fli->started_p = 1;
2862 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2863 put_mangled_filename (f, v->line.file);
2864 oprintf (f, "[] = {\n");
2867 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2870 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2871 "gt_ggc_rtab");
2873 for (v = variables; v; v = v->next)
2875 outf_p f = get_output_file_with_visibility (v->line.file);
2876 struct flist *fli;
2877 int skip_p = 1;
2878 options_p o;
2880 for (o = v->opt; o; o = o->next)
2881 if (strcmp (o->name, "deletable") == 0)
2882 skip_p = 0;
2883 else if (strcmp (o->name, "if_marked") == 0)
2884 skip_p = 1;
2886 if (skip_p)
2887 continue;
2889 for (fli = flp; fli; fli = fli->next)
2890 if (fli->f == f)
2891 break;
2892 if (! fli->started_p)
2894 fli->started_p = 1;
2896 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2897 put_mangled_filename (f, v->line.file);
2898 oprintf (f, "[] = {\n");
2901 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2902 v->name, v->name);
2905 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2906 "gt_ggc_deletable_rtab");
2908 for (v = variables; v; v = v->next)
2910 outf_p f = get_output_file_with_visibility (v->line.file);
2911 struct flist *fli;
2912 const char *if_marked = NULL;
2913 int length_p = 0;
2914 options_p o;
2916 for (o = v->opt; o; o = o->next)
2917 if (strcmp (o->name, "length") == 0)
2918 length_p = 1;
2919 else if (strcmp (o->name, "if_marked") == 0)
2920 if_marked = o->info;
2922 if (if_marked == NULL)
2923 continue;
2925 if (v->type->kind != TYPE_POINTER
2926 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2927 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2929 error_at_line (&v->line, "if_marked option used but not hash table");
2930 continue;
2933 for (fli = flp; fli; fli = fli->next)
2934 if (fli->f == f)
2935 break;
2936 if (! fli->started_p)
2938 fli->started_p = 1;
2940 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2941 put_mangled_filename (f, v->line.file);
2942 oprintf (f, "[] = {\n");
2945 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2946 v->name, length_p, &v->line, if_marked);
2949 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2950 "gt_ggc_cache_rtab");
2952 for (v = variables; v; v = v->next)
2954 outf_p f = get_output_file_with_visibility (v->line.file);
2955 struct flist *fli;
2956 int length_p = 0;
2957 int if_marked_p = 0;
2958 options_p o;
2960 for (o = v->opt; o; o = o->next)
2961 if (strcmp (o->name, "length") == 0)
2962 length_p = 1;
2963 else if (strcmp (o->name, "if_marked") == 0)
2964 if_marked_p = 1;
2966 if (! if_marked_p)
2967 continue;
2969 for (fli = flp; fli; fli = fli->next)
2970 if (fli->f == f)
2971 break;
2972 if (! fli->started_p)
2974 fli->started_p = 1;
2976 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2977 put_mangled_filename (f, v->line.file);
2978 oprintf (f, "[] = {\n");
2981 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2984 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2985 "gt_pch_cache_rtab");
2987 for (v = variables; v; v = v->next)
2989 outf_p f = get_output_file_with_visibility (v->line.file);
2990 struct flist *fli;
2991 int skip_p = 0;
2992 options_p o;
2994 for (o = v->opt; o; o = o->next)
2995 if (strcmp (o->name, "deletable") == 0
2996 || strcmp (o->name, "if_marked") == 0)
2997 skip_p = 1;
2999 if (skip_p)
3000 continue;
3002 if (! contains_scalar_p (v->type))
3003 continue;
3005 for (fli = flp; fli; fli = fli->next)
3006 if (fli->f == f)
3007 break;
3008 if (! fli->started_p)
3010 fli->started_p = 1;
3012 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3013 put_mangled_filename (f, v->line.file);
3014 oprintf (f, "[] = {\n");
3017 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3018 v->name, v->name);
3021 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3022 "gt_pch_scalar_rtab");
3026 extern int main (int argc, char **argv);
3028 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
3030 unsigned i;
3031 static struct fileloc pos = { __FILE__, __LINE__ };
3032 unsigned j;
3034 gen_rtx_next ();
3036 srcdir_len = strlen (srcdir);
3038 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3039 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3040 do_scalar_typedef ("double_int", &pos);
3041 do_scalar_typedef ("uint8", &pos);
3042 do_scalar_typedef ("jword", &pos);
3043 do_scalar_typedef ("JCF_u2", &pos);
3044 #ifdef USE_MAPPED_LOCATION
3045 do_scalar_typedef ("location_t", &pos);
3046 do_scalar_typedef ("source_locus", &pos);
3047 #endif
3048 do_scalar_typedef ("void", &pos);
3050 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3052 do_typedef ("HARD_REG_SET", create_array (
3053 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3054 "2"), &pos);
3056 for (i = 0; i < NUM_GT_FILES; i++)
3058 int dupflag = 0;
3059 /* Omit if already seen. */
3060 for (j = 0; j < i; j++)
3062 if (!strcmp (all_files[i], all_files[j]))
3064 dupflag = 1;
3065 break;
3068 if (!dupflag)
3069 parse_file (all_files[i]);
3070 #ifndef USE_MAPPED_LOCATION
3071 /* temporary kludge - gengtype doesn't handle conditionals.
3072 Manually add source_locus *after* we've processed input.h. */
3073 if (i == 0)
3074 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3075 #endif
3078 if (hit_error != 0)
3079 exit (1);
3081 set_gc_used (variables);
3083 open_base_files ();
3084 write_enum_defn (structures, param_structs);
3085 write_types (structures, param_structs, &ggc_wtd);
3086 write_types (structures, param_structs, &pch_wtd);
3087 write_local (structures, param_structs);
3088 write_roots (variables);
3089 write_rtx_next ();
3090 close_output_files ();
3092 return (hit_error != 0);