]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/gengtype.c
alpha.c (alpha_start_function): Use switch_to_section.
[thirdparty/gcc.git] / gcc / gengtype.c
1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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.
10
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.
15
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. */
20
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"
28
29 /* Nonzero iff an error has occurred. */
30 static int hit_error = 0;
31
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);
36
37 /* Report an error at POS, printing MSG. */
38
39 void
40 error_at_line (struct fileloc *pos, const char *msg, ...)
41 {
42 va_list ap;
43
44 va_start (ap, msg);
45
46 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
47 vfprintf (stderr, msg, ap);
48 fputc ('\n', stderr);
49 hit_error = 1;
50
51 va_end (ap);
52 }
53
54 /* vasprintf, but produces fatal message on out-of-memory. */
55 int
56 xvasprintf (char **result, const char *format, va_list args)
57 {
58 int ret = vasprintf (result, format, args);
59 if (*result == NULL || ret < 0)
60 {
61 fputs ("gengtype: out of memory", stderr);
62 xexit (1);
63 }
64 return ret;
65 }
66
67 /* Wrapper for xvasprintf. */
68 char *
69 xasprintf (const char *format, ...)
70 {
71 char *result;
72 va_list ap;
73
74 va_start (ap, format);
75 xvasprintf (&result, format, ap);
76 va_end (ap);
77 return result;
78 }
79
80 /* The one and only TYPE_STRING. */
81
82 struct type string_type = {
83 TYPE_STRING, NULL, NULL, GC_USED, {0}
84 };
85
86 /* Lists of various things. */
87
88 static pair_p typedefs;
89 static type_p structures;
90 static type_p param_structs;
91 static pair_p variables;
92
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);
98
99 /* Define S as a typedef to T at POS. */
100
101 void
102 do_typedef (const char *s, type_p t, struct fileloc *pos)
103 {
104 pair_p p;
105
106 for (p = typedefs; p != NULL; p = p->next)
107 if (strcmp (p->name, s) == 0)
108 {
109 if (p->type != t)
110 {
111 error_at_line (pos, "type `%s' previously defined", s);
112 error_at_line (&p->line, "previously defined here");
113 }
114 return;
115 }
116
117 p = XNEW (struct pair);
118 p->next = typedefs;
119 p->name = s;
120 p->type = t;
121 p->line = *pos;
122 typedefs = p;
123 }
124
125 /* Define S as a typename of a scalar. */
126
127 static void
128 do_scalar_typedef (const char *s, struct fileloc *pos)
129 {
130 do_typedef (s, create_scalar_type (s, strlen (s)), pos);
131 }
132
133 /* Return the type previously defined for S. Use POS to report errors. */
134
135 type_p
136 resolve_typedef (const char *s, struct fileloc *pos)
137 {
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);
144 }
145
146 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
147 at POS with fields FIELDS and options O. */
148
149 void
150 new_structure (const char *name, int isunion, struct fileloc *pos,
151 pair_p fields, options_p o)
152 {
153 type_p si;
154 type_p s = NULL;
155 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
156
157 for (si = structures; si != NULL; si = si->next)
158 if (strcmp (name, si->u.s.tag) == 0
159 && UNION_P (si) == isunion)
160 {
161 type_p ls = NULL;
162 if (si->kind == TYPE_LANG_STRUCT)
163 {
164 ls = si;
165
166 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
167 if (si->u.s.bitmap == bitmap)
168 s = si;
169 }
170 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
171 {
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;
181 }
182 else
183 s = si;
184
185 if (ls != NULL && s == NULL)
186 {
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;
191 }
192 break;
193 }
194
195 if (s == NULL)
196 {
197 s = XCNEW (struct type);
198 s->next = structures;
199 structures = s;
200 }
201
202 if (s->u.s.line.file != NULL
203 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
204 {
205 error_at_line (pos, "duplicate structure definition");
206 error_at_line (&s->u.s.line, "previous definition here");
207 }
208
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;
217 }
218
219 /* Return the previously-defined structure with tag NAME (or a union
220 iff ISUNION is nonzero), or a new empty structure or union if none
221 was defined previously. */
222
223 type_p
224 find_structure (const char *name, int isunion)
225 {
226 type_p s;
227
228 for (s = structures; s != NULL; s = s->next)
229 if (strcmp (name, s->u.s.tag) == 0
230 && UNION_P (s) == isunion)
231 return s;
232
233 s = XCNEW (struct type);
234 s->next = structures;
235 structures = s;
236 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
237 s->u.s.tag = name;
238 structures = s;
239 return s;
240 }
241
242 /* Return the previously-defined parameterized structure for structure
243 T and parameters PARAM, or a new parameterized empty structure or
244 union if none was defined previously. */
245
246 static type_p
247 find_param_structure (type_p t, type_p param[NUM_PARAM])
248 {
249 type_p res;
250
251 for (res = param_structs; res; res = res->next)
252 if (res->u.param_struct.stru == t
253 && memcmp (res->u.param_struct.param, param,
254 sizeof (type_p) * NUM_PARAM) == 0)
255 break;
256 if (res == NULL)
257 {
258 res = XCNEW (struct type);
259 res->kind = TYPE_PARAM_STRUCT;
260 res->next = param_structs;
261 param_structs = res;
262 res->u.param_struct.stru = t;
263 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
264 }
265 return res;
266 }
267
268 /* Return a scalar type with name NAME. */
269
270 type_p
271 create_scalar_type (const char *name, size_t name_len)
272 {
273 type_p r = XCNEW (struct type);
274 r->kind = TYPE_SCALAR;
275 r->u.sc = (char *) xmemdup (name, name_len, name_len + 1);
276 return r;
277 }
278
279 /* Return a pointer to T. */
280
281 type_p
282 create_pointer (type_p t)
283 {
284 if (! t->pointer_to)
285 {
286 type_p r = XCNEW (struct type);
287 r->kind = TYPE_POINTER;
288 r->u.p = t;
289 t->pointer_to = r;
290 }
291 return t->pointer_to;
292 }
293
294 /* Return an array of length LEN. */
295
296 type_p
297 create_array (type_p t, const char *len)
298 {
299 type_p v;
300
301 v = XCNEW (struct type);
302 v->kind = TYPE_ARRAY;
303 v->u.a.p = t;
304 v->u.a.len = len;
305 return v;
306 }
307
308 /* Return an options structure with name NAME and info INFO. */
309 options_p
310 create_option (const char *name, void *info)
311 {
312 options_p o = XNEW (struct options);
313 o->name = name;
314 o->info = (const char*) info;
315 return o;
316 }
317
318 /* Add a variable named S of type T with options O defined at POS,
319 to `variables'. */
320
321 void
322 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
323 {
324 pair_p n;
325 n = XNEW (struct pair);
326 n->name = s;
327 n->type = t;
328 n->line = *pos;
329 n->opt = o;
330 n->next = variables;
331 variables = n;
332 }
333
334 /* We don't care how long a CONST_DOUBLE is. */
335 #define CONST_DOUBLE_FORMAT "ww"
336 /* We don't want to see codes that are only for generator files. */
337 #undef GENERATOR_FILE
338
339 enum rtx_code {
340 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
341 #include "rtl.def"
342 #undef DEF_RTL_EXPR
343 NUM_RTX_CODE
344 };
345
346 static const char * const rtx_name[NUM_RTX_CODE] = {
347 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
348 #include "rtl.def"
349 #undef DEF_RTL_EXPR
350 };
351
352 static const char * const rtx_format[NUM_RTX_CODE] = {
353 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
354 #include "rtl.def"
355 #undef DEF_RTL_EXPR
356 };
357
358 static int rtx_next_new[NUM_RTX_CODE];
359
360 /* We also need codes and names for insn notes (not register notes).
361 Note that we do *not* bias the note values here. */
362 enum insn_note {
363 #define DEF_INSN_NOTE(NAME) NAME,
364 #include "insn-notes.def"
365 #undef DEF_INSN_NOTE
366
367 NOTE_INSN_MAX
368 };
369
370 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
371 default field for line number notes. */
372 static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
373 #define DEF_INSN_NOTE(NAME) #NAME,
374 #include "insn-notes.def"
375 #undef DEF_INSN_NOTE
376 };
377
378 #undef CONST_DOUBLE_FORMAT
379 #define GENERATOR_FILE
380
381 /* Generate the contents of the rtx_next array. This really doesn't belong
382 in gengtype at all, but it's needed for adjust_field_rtx_def. */
383
384 static void
385 gen_rtx_next (void)
386 {
387 int i;
388 for (i = 0; i < NUM_RTX_CODE; i++)
389 {
390 int k;
391
392 rtx_next_new[i] = -1;
393 if (strncmp (rtx_format[i], "iuu", 3) == 0)
394 rtx_next_new[i] = 2;
395 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
396 rtx_next_new[i] = 1;
397 else
398 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
399 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
400 rtx_next_new[i] = k;
401 }
402 }
403
404 /* Write out the contents of the rtx_next array. */
405 static void
406 write_rtx_next (void)
407 {
408 outf_p f = get_output_file_with_visibility (NULL);
409 int i;
410
411 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
412 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
413 for (i = 0; i < NUM_RTX_CODE; i++)
414 if (rtx_next_new[i] == -1)
415 oprintf (f, " 0,\n");
416 else
417 oprintf (f,
418 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
419 rtx_next_new[i]);
420 oprintf (f, "};\n");
421 }
422
423 /* Handle `special("rtx_def")'. This is a special case for field
424 `fld' of struct rtx_def, which is an array of unions whose values
425 are based in a complex way on the type of RTL. */
426
427 static type_p
428 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
429 {
430 pair_p flds = NULL;
431 options_p nodot;
432 int i;
433 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
434 type_p bitmap_tp, basic_block_tp, reg_attrs_tp;
435
436 if (t->kind != TYPE_UNION)
437 {
438 error_at_line (&lexer_line,
439 "special `rtx_def' must be applied to a union");
440 return &string_type;
441 }
442
443 nodot = XNEW (struct options);
444 nodot->next = NULL;
445 nodot->name = "dot";
446 nodot->info = "";
447
448 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
449 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
450 tree_tp = create_pointer (find_structure ("tree_node", 1));
451 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
452 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
453 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
454 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
455 scalar_tp = create_scalar_type ("rtunion scalar", 14);
456
457 {
458 pair_p note_flds = NULL;
459 int c;
460
461 for (c = 0; c <= NOTE_INSN_MAX; c++)
462 {
463 pair_p old_note_flds = note_flds;
464
465 note_flds = XNEW (struct pair);
466 note_flds->line.file = __FILE__;
467 note_flds->line.line = __LINE__;
468 note_flds->opt = XNEW (struct options);
469 note_flds->opt->next = nodot;
470 note_flds->opt->name = "tag";
471 note_flds->opt->info = note_insn_name[c];
472 note_flds->next = old_note_flds;
473
474 switch (c)
475 {
476 /* NOTE_INSN_MAX is used as the default field for line
477 number notes. */
478 case NOTE_INSN_MAX:
479 note_flds->opt->name = "default";
480 note_flds->name = "rt_str";
481 note_flds->type = &string_type;
482 break;
483
484 case NOTE_INSN_BLOCK_BEG:
485 case NOTE_INSN_BLOCK_END:
486 note_flds->name = "rt_tree";
487 note_flds->type = tree_tp;
488 break;
489
490 case NOTE_INSN_EXPECTED_VALUE:
491 case NOTE_INSN_VAR_LOCATION:
492 note_flds->name = "rt_rtx";
493 note_flds->type = rtx_tp;
494 break;
495
496 default:
497 note_flds->name = "rt_int";
498 note_flds->type = scalar_tp;
499 break;
500 }
501 }
502 new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL);
503 }
504
505 note_union_tp = find_structure ("rtx_def_note_subunion", 1);
506
507 for (i = 0; i < NUM_RTX_CODE; i++)
508 {
509 pair_p old_flds = flds;
510 pair_p subfields = NULL;
511 size_t aindex, nmindex;
512 const char *sname;
513 char *ftag;
514
515 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
516 {
517 pair_p old_subf = subfields;
518 type_p t;
519 const char *subname;
520
521 switch (rtx_format[i][aindex])
522 {
523 case '*':
524 case 'i':
525 case 'n':
526 case 'w':
527 t = scalar_tp;
528 subname = "rt_int";
529 break;
530
531 case '0':
532 if (i == MEM && aindex == 1)
533 t = mem_attrs_tp, subname = "rt_mem";
534 else if (i == JUMP_INSN && aindex == 9)
535 t = rtx_tp, subname = "rt_rtx";
536 else if (i == CODE_LABEL && aindex == 4)
537 t = scalar_tp, subname = "rt_int";
538 else if (i == CODE_LABEL && aindex == 5)
539 t = rtx_tp, subname = "rt_rtx";
540 else if (i == LABEL_REF
541 && (aindex == 1 || aindex == 2))
542 t = rtx_tp, subname = "rt_rtx";
543 else if (i == NOTE && aindex == 4)
544 t = note_union_tp, subname = "";
545 else if (i == NOTE && aindex >= 7)
546 t = scalar_tp, subname = "rt_int";
547 else if (i == ADDR_DIFF_VEC && aindex == 4)
548 t = scalar_tp, subname = "rt_int";
549 else if (i == VALUE && aindex == 0)
550 t = scalar_tp, subname = "rt_int";
551 else if (i == REG && aindex == 1)
552 t = scalar_tp, subname = "rt_int";
553 else if (i == REG && aindex == 2)
554 t = reg_attrs_tp, subname = "rt_reg";
555 else if (i == SCRATCH && aindex == 0)
556 t = scalar_tp, subname = "rt_int";
557 else if (i == SYMBOL_REF && aindex == 1)
558 t = scalar_tp, subname = "rt_int";
559 else if (i == SYMBOL_REF && aindex == 2)
560 t = tree_tp, subname = "rt_tree";
561 else if (i == BARRIER && aindex >= 3)
562 t = scalar_tp, subname = "rt_int";
563 else
564 {
565 error_at_line (&lexer_line,
566 "rtx type `%s' has `0' in position %lu, can't handle",
567 rtx_name[i], (unsigned long) aindex);
568 t = &string_type;
569 subname = "rt_int";
570 }
571 break;
572
573 case 's':
574 case 'S':
575 case 'T':
576 t = &string_type;
577 subname = "rt_str";
578 break;
579
580 case 'e':
581 case 'u':
582 t = rtx_tp;
583 subname = "rt_rtx";
584 break;
585
586 case 'E':
587 case 'V':
588 t = rtvec_tp;
589 subname = "rt_rtvec";
590 break;
591
592 case 't':
593 t = tree_tp;
594 subname = "rt_tree";
595 break;
596
597 case 'b':
598 t = bitmap_tp;
599 subname = "rt_bit";
600 break;
601
602 case 'B':
603 t = basic_block_tp;
604 subname = "rt_bb";
605 break;
606
607 default:
608 error_at_line (&lexer_line,
609 "rtx type `%s' has `%c' in position %lu, can't handle",
610 rtx_name[i], rtx_format[i][aindex],
611 (unsigned long)aindex);
612 t = &string_type;
613 subname = "rt_int";
614 break;
615 }
616
617 subfields = XNEW (struct pair);
618 subfields->next = old_subf;
619 subfields->type = t;
620 subfields->name = xasprintf (".fld[%lu].%s", (unsigned long)aindex,
621 subname);
622 subfields->line.file = __FILE__;
623 subfields->line.line = __LINE__;
624 if (t == note_union_tp)
625 {
626 subfields->opt = XNEW (struct options);
627 subfields->opt->next = nodot;
628 subfields->opt->name = "desc";
629 subfields->opt->info = "NOTE_LINE_NUMBER (&%0)";
630 }
631 else
632 subfields->opt = nodot;
633 }
634
635 flds = XNEW (struct pair);
636 flds->next = old_flds;
637 flds->name = "";
638 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
639 new_structure (sname, 0, &lexer_line, subfields, NULL);
640 flds->type = find_structure (sname, 0);
641 flds->line.file = __FILE__;
642 flds->line.line = __LINE__;
643 flds->opt = XNEW (struct options);
644 flds->opt->next = nodot;
645 flds->opt->name = "tag";
646 ftag = xstrdup (rtx_name[i]);
647 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
648 ftag[nmindex] = TOUPPER (ftag[nmindex]);
649 flds->opt->info = ftag;
650 }
651
652 new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
653 return find_structure ("rtx_def_subunion", 1);
654 }
655
656 /* Handle `special("tree_exp")'. This is a special case for
657 field `operands' of struct tree_exp, which although it claims to contain
658 pointers to trees, actually sometimes contains pointers to RTL too.
659 Passed T, the old type of the field, and OPT its options. Returns
660 a new type for the field. */
661
662 static type_p
663 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
664 {
665 pair_p flds;
666 options_p nodot;
667
668 if (t->kind != TYPE_ARRAY)
669 {
670 error_at_line (&lexer_line,
671 "special `tree_exp' must be applied to an array");
672 return &string_type;
673 }
674
675 nodot = XNEW (struct options);
676 nodot->next = NULL;
677 nodot->name = "dot";
678 nodot->info = "";
679
680 flds = XNEW (struct pair);
681 flds->next = NULL;
682 flds->name = "";
683 flds->type = t;
684 flds->line.file = __FILE__;
685 flds->line.line = __LINE__;
686 flds->opt = XNEW (struct options);
687 flds->opt->next = nodot;
688 flds->opt->name = "length";
689 flds->opt->info = "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
690 {
691 options_p oldopt = flds->opt;
692 flds->opt = XNEW (struct options);
693 flds->opt->next = oldopt;
694 flds->opt->name = "default";
695 flds->opt->info = "";
696 }
697
698 new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
699 return find_structure ("tree_exp_subunion", 1);
700 }
701
702 /* Perform any special processing on a type T, about to become the type
703 of a field. Return the appropriate type for the field.
704 At present:
705 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
706 - Similarly for arrays of pointer-to-char;
707 - Converts structures for which a parameter is provided to
708 TYPE_PARAM_STRUCT;
709 - Handles "special" options.
710 */
711
712 type_p
713 adjust_field_type (type_p t, options_p opt)
714 {
715 int length_p = 0;
716 const int pointer_p = t->kind == TYPE_POINTER;
717 type_p params[NUM_PARAM];
718 int params_p = 0;
719 int i;
720
721 for (i = 0; i < NUM_PARAM; i++)
722 params[i] = NULL;
723
724 for (; opt; opt = opt->next)
725 if (strcmp (opt->name, "length") == 0)
726 length_p = 1;
727 else if (strcmp (opt->name, "param_is") == 0
728 || (strncmp (opt->name, "param", 5) == 0
729 && ISDIGIT (opt->name[5])
730 && strcmp (opt->name + 6, "_is") == 0))
731 {
732 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
733
734 if (! UNION_OR_STRUCT_P (t)
735 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
736 {
737 error_at_line (&lexer_line,
738 "option `%s' may only be applied to structures or structure pointers",
739 opt->name);
740 return t;
741 }
742
743 params_p = 1;
744 if (params[num] != NULL)
745 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
746 if (! ISDIGIT (opt->name[5]))
747 params[num] = create_pointer ((type_p) opt->info);
748 else
749 params[num] = (type_p) opt->info;
750 }
751 else if (strcmp (opt->name, "special") == 0)
752 {
753 const char *special_name = opt->info;
754 if (strcmp (special_name, "tree_exp") == 0)
755 t = adjust_field_tree_exp (t, opt);
756 else if (strcmp (special_name, "rtx_def") == 0)
757 t = adjust_field_rtx_def (t, opt);
758 else
759 error_at_line (&lexer_line, "unknown special `%s'", special_name);
760 }
761
762 if (params_p)
763 {
764 type_p realt;
765
766 if (pointer_p)
767 t = t->u.p;
768 realt = find_param_structure (t, params);
769 t = pointer_p ? create_pointer (realt) : realt;
770 }
771
772 if (! length_p
773 && pointer_p
774 && t->u.p->kind == TYPE_SCALAR
775 && (strcmp (t->u.p->u.sc, "char") == 0
776 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
777 return &string_type;
778 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
779 && t->u.a.p->u.p->kind == TYPE_SCALAR
780 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
781 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
782 return create_array (&string_type, t->u.a.len);
783
784 return t;
785 }
786
787 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
788 and information about the correspondence between token types and fields
789 in TYPEINFO. POS is used for error messages. */
790
791 void
792 note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
793 struct fileloc *pos)
794 {
795 pair_p p;
796 pair_p *p_p;
797
798 for (p = typeinfo; p; p = p->next)
799 {
800 pair_p m;
801
802 if (p->name == NULL)
803 continue;
804
805 if (p->type == (type_p) 1)
806 {
807 pair_p pp;
808 int ok = 0;
809
810 for (pp = typeinfo; pp; pp = pp->next)
811 if (pp->type != (type_p) 1
812 && strcmp (pp->opt->info, p->opt->info) == 0)
813 {
814 ok = 1;
815 break;
816 }
817 if (! ok)
818 continue;
819 }
820
821 for (m = fields; m; m = m->next)
822 if (strcmp (m->name, p->name) == 0)
823 p->type = m->type;
824 if (p->type == NULL)
825 {
826 error_at_line (&p->line,
827 "couldn't match fieldname `%s'", p->name);
828 p->name = NULL;
829 }
830 }
831
832 p_p = &typeinfo;
833 while (*p_p)
834 {
835 pair_p p = *p_p;
836
837 if (p->name == NULL
838 || p->type == (type_p) 1)
839 *p_p = p->next;
840 else
841 p_p = &p->next;
842 }
843
844 new_structure ("yy_union", 1, pos, typeinfo, o);
845 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
846 }
847 \f
848 static void process_gc_options (options_p, enum gc_used_enum,
849 int *, int *, int *, type_p *);
850 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
851 static void set_gc_used (pair_p);
852
853 /* Handle OPT for set_gc_used_type. */
854
855 static void
856 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
857 int *pass_param, int *length, type_p *nested_ptr)
858 {
859 options_p o;
860 for (o = opt; o; o = o->next)
861 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
862 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
863 else if (strcmp (o->name, "maybe_undef") == 0)
864 *maybe_undef = 1;
865 else if (strcmp (o->name, "use_params") == 0)
866 *pass_param = 1;
867 else if (strcmp (o->name, "length") == 0)
868 *length = 1;
869 else if (strcmp (o->name, "nested_ptr") == 0)
870 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
871 }
872
873 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
874
875 static void
876 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
877 {
878 if (t->gc_used >= level)
879 return;
880
881 t->gc_used = level;
882
883 switch (t->kind)
884 {
885 case TYPE_STRUCT:
886 case TYPE_UNION:
887 {
888 pair_p f;
889 int dummy;
890 type_p dummy2;
891
892 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy,
893 &dummy2);
894
895 for (f = t->u.s.fields; f; f = f->next)
896 {
897 int maybe_undef = 0;
898 int pass_param = 0;
899 int length = 0;
900 type_p nested_ptr = NULL;
901 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
902 &length, &nested_ptr);
903
904 if (nested_ptr && f->type->kind == TYPE_POINTER)
905 set_gc_used_type (nested_ptr, GC_POINTED_TO,
906 pass_param ? param : NULL);
907 else if (length && f->type->kind == TYPE_POINTER)
908 set_gc_used_type (f->type->u.p, GC_USED, NULL);
909 else if (maybe_undef && f->type->kind == TYPE_POINTER)
910 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
911 else if (pass_param && f->type->kind == TYPE_POINTER && param)
912 set_gc_used_type (find_param_structure (f->type->u.p, param),
913 GC_POINTED_TO, NULL);
914 else
915 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
916 }
917 break;
918 }
919
920 case TYPE_POINTER:
921 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
922 break;
923
924 case TYPE_ARRAY:
925 set_gc_used_type (t->u.a.p, GC_USED, param);
926 break;
927
928 case TYPE_LANG_STRUCT:
929 for (t = t->u.s.lang_struct; t; t = t->next)
930 set_gc_used_type (t, level, param);
931 break;
932
933 case TYPE_PARAM_STRUCT:
934 {
935 int i;
936 for (i = 0; i < NUM_PARAM; i++)
937 if (t->u.param_struct.param[i] != 0)
938 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
939 }
940 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
941 level = GC_POINTED_TO;
942 else
943 level = GC_USED;
944 t->u.param_struct.stru->gc_used = GC_UNUSED;
945 set_gc_used_type (t->u.param_struct.stru, level,
946 t->u.param_struct.param);
947 break;
948
949 default:
950 break;
951 }
952 }
953
954 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
955
956 static void
957 set_gc_used (pair_p variables)
958 {
959 pair_p p;
960 for (p = variables; p; p = p->next)
961 set_gc_used_type (p->type, GC_USED, NULL);
962 }
963 \f
964 /* File mapping routines. For each input file, there is one output .c file
965 (but some output files have many input files), and there is one .h file
966 for the whole build. */
967
968 /* The list of output files. */
969 static outf_p output_files;
970
971 /* The output header file that is included into pretty much every
972 source file. */
973 static outf_p header_file;
974
975 /* Number of files specified in gtfiles. */
976 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
977
978 /* Number of files in the language files array. */
979 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
980
981 /* Length of srcdir name. */
982 static int srcdir_len = 0;
983
984 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
985 outf_p base_files[NUM_BASE_FILES];
986
987 static outf_p create_file (const char *, const char *);
988 static const char * get_file_basename (const char *);
989
990 /* Create and return an outf_p for a new file for NAME, to be called
991 ONAME. */
992
993 static outf_p
994 create_file (const char *name, const char *oname)
995 {
996 static const char *const hdr[] = {
997 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
998 "\n",
999 "This file is part of GCC.\n",
1000 "\n",
1001 "GCC is free software; you can redistribute it and/or modify it under\n",
1002 "the terms of the GNU General Public License as published by the Free\n",
1003 "Software Foundation; either version 2, or (at your option) any later\n",
1004 "version.\n",
1005 "\n",
1006 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1007 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1008 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1009 "for more details.\n",
1010 "\n",
1011 "You should have received a copy of the GNU General Public License\n",
1012 "along with GCC; see the file COPYING. If not, write to the Free\n",
1013 "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1014 "02110-1301, USA. */\n",
1015 "\n",
1016 "/* This file is machine generated. Do not edit. */\n"
1017 };
1018 outf_p f;
1019 size_t i;
1020
1021 f = XCNEW (struct outf);
1022 f->next = output_files;
1023 f->name = oname;
1024 output_files = f;
1025
1026 oprintf (f, "/* Type information for %s.\n", name);
1027 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1028 oprintf (f, "%s", hdr[i]);
1029 return f;
1030 }
1031
1032 /* Print, like fprintf, to O. */
1033 void
1034 oprintf (outf_p o, const char *format, ...)
1035 {
1036 char *s;
1037 size_t slength;
1038 va_list ap;
1039
1040 va_start (ap, format);
1041 slength = xvasprintf (&s, format, ap);
1042
1043 if (o->bufused + slength > o->buflength)
1044 {
1045 size_t new_len = o->buflength;
1046 if (new_len == 0)
1047 new_len = 1024;
1048 do {
1049 new_len *= 2;
1050 } while (o->bufused + slength >= new_len);
1051 o->buf = XRESIZEVEC (char, o->buf, new_len);
1052 o->buflength = new_len;
1053 }
1054 memcpy (o->buf + o->bufused, s, slength);
1055 o->bufused += slength;
1056 free (s);
1057 va_end (ap);
1058 }
1059
1060 /* Open the global header file and the language-specific header files. */
1061
1062 static void
1063 open_base_files (void)
1064 {
1065 size_t i;
1066
1067 header_file = create_file ("GCC", "gtype-desc.h");
1068
1069 for (i = 0; i < NUM_BASE_FILES; i++)
1070 base_files[i] = create_file (lang_dir_names[i],
1071 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1072
1073 /* gtype-desc.c is a little special, so we create it here. */
1074 {
1075 /* The order of files here matters very much. */
1076 static const char *const ifiles [] = {
1077 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1078 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1079 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1080 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1081 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1082 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1083 "except.h", "output.h", NULL
1084 };
1085 const char *const *ifp;
1086 outf_p gtype_desc_c;
1087
1088 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1089 for (ifp = ifiles; *ifp; ifp++)
1090 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1091 }
1092 }
1093
1094 /* Determine the pathname to F relative to $(srcdir). */
1095
1096 static const char *
1097 get_file_basename (const char *f)
1098 {
1099 const char *basename;
1100 unsigned i;
1101
1102 basename = strrchr (f, '/');
1103
1104 if (!basename)
1105 return f;
1106
1107 basename++;
1108
1109 for (i = 1; i < NUM_BASE_FILES; i++)
1110 {
1111 const char * s1;
1112 const char * s2;
1113 int l1;
1114 int l2;
1115 s1 = basename - strlen (lang_dir_names [i]) - 1;
1116 s2 = lang_dir_names [i];
1117 l1 = strlen (s1);
1118 l2 = strlen (s2);
1119 if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1120 {
1121 basename -= l2 + 1;
1122 if ((basename - f - 1) != srcdir_len)
1123 fatal ("filename `%s' should be preceded by $srcdir", f);
1124 break;
1125 }
1126 }
1127
1128 return basename;
1129 }
1130
1131 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1132 INPUT_FILE is used by <lang>.
1133
1134 This function should be written to assume that a file _is_ used
1135 if the situation is unclear. If it wrongly assumes a file _is_ used,
1136 a linker error will result. If it wrongly assumes a file _is not_ used,
1137 some GC roots may be missed, which is a much harder-to-debug problem. */
1138
1139 unsigned
1140 get_base_file_bitmap (const char *input_file)
1141 {
1142 const char *basename = get_file_basename (input_file);
1143 const char *slashpos = strchr (basename, '/');
1144 unsigned j;
1145 unsigned k;
1146 unsigned bitmap;
1147
1148 /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1149 it belongs to the corresponding language. The file may belong to other
1150 languages as well (which is checked for below). */
1151
1152 if (slashpos)
1153 {
1154 size_t i;
1155 for (i = 1; i < NUM_BASE_FILES; i++)
1156 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1157 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1158 {
1159 /* It's in a language directory, set that language. */
1160 bitmap = 1 << i;
1161 }
1162 }
1163
1164 /* If it's in any config-lang.in, then set for the languages
1165 specified. */
1166
1167 bitmap = 0;
1168
1169 for (j = 0; j < NUM_LANG_FILES; j++)
1170 {
1171 if (!strcmp(input_file, lang_files[j]))
1172 {
1173 for (k = 0; k < NUM_BASE_FILES; k++)
1174 {
1175 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1176 bitmap |= (1 << k);
1177 }
1178 }
1179 }
1180
1181 /* Otherwise, set all languages. */
1182 if (!bitmap)
1183 bitmap = (1 << NUM_BASE_FILES) - 1;
1184
1185 return bitmap;
1186 }
1187
1188 /* An output file, suitable for definitions, that can see declarations
1189 made in INPUT_FILE and is linked into every language that uses
1190 INPUT_FILE. */
1191
1192 outf_p
1193 get_output_file_with_visibility (const char *input_file)
1194 {
1195 outf_p r;
1196 size_t len;
1197 const char *basename;
1198 const char *for_name;
1199 const char *output_name;
1200
1201 /* This can happen when we need a file with visibility on a
1202 structure that we've never seen. We have to just hope that it's
1203 globally visible. */
1204 if (input_file == NULL)
1205 input_file = "system.h";
1206
1207 /* Determine the output file name. */
1208 basename = get_file_basename (input_file);
1209
1210 len = strlen (basename);
1211 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1212 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1213 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1214 {
1215 char *s;
1216
1217 output_name = s = xasprintf ("gt-%s", basename);
1218 for (; *s != '.'; s++)
1219 if (! ISALNUM (*s) && *s != '-')
1220 *s = '-';
1221 memcpy (s, ".h", sizeof (".h"));
1222 for_name = basename;
1223 }
1224 /* Some headers get used by more than one front-end; hence, it
1225 would be inappropriate to spew them out to a single gtype-<lang>.h
1226 (and gengtype doesn't know how to direct spewage into multiple
1227 gtype-<lang>.h headers at this time). Instead, we pair up these
1228 headers with source files (and their special purpose gt-*.h headers). */
1229 else if (strcmp (basename, "c-common.h") == 0)
1230 output_name = "gt-c-common.h", for_name = "c-common.c";
1231 else if (strcmp (basename, "c-tree.h") == 0)
1232 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1233 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1234 && strcmp (basename + 3, "cp-tree.h") == 0)
1235 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1236 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1237 && strcmp (basename + 3, "decl.h") == 0)
1238 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1239 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1240 && strcmp (basename + 3, "name-lookup.h") == 0)
1241 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1242 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1243 && strcmp (basename + 5, "objc-act.h") == 0)
1244 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1245 else
1246 {
1247 size_t i;
1248
1249 for (i = 0; i < NUM_BASE_FILES; i++)
1250 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1251 && basename[strlen(lang_dir_names[i])] == '/')
1252 return base_files[i];
1253
1254 output_name = "gtype-desc.c";
1255 for_name = NULL;
1256 }
1257
1258 /* Look through to see if we've ever seen this output filename before. */
1259 for (r = output_files; r; r = r->next)
1260 if (strcmp (r->name, output_name) == 0)
1261 return r;
1262
1263 /* If not, create it. */
1264 r = create_file (for_name, output_name);
1265
1266 return r;
1267 }
1268
1269 /* The name of an output file, suitable for definitions, that can see
1270 declarations made in INPUT_FILE and is linked into every language
1271 that uses INPUT_FILE. */
1272
1273 const char *
1274 get_output_file_name (const char *input_file)
1275 {
1276 return get_output_file_with_visibility (input_file)->name;
1277 }
1278
1279 /* Copy the output to its final destination,
1280 but don't unnecessarily change modification times. */
1281
1282 static void
1283 close_output_files (void)
1284 {
1285 outf_p of;
1286
1287 for (of = output_files; of; of = of->next)
1288 {
1289 FILE * newfile;
1290
1291 newfile = fopen (of->name, "r");
1292 if (newfile != NULL )
1293 {
1294 int no_write_p;
1295 size_t i;
1296
1297 for (i = 0; i < of->bufused; i++)
1298 {
1299 int ch;
1300 ch = fgetc (newfile);
1301 if (ch == EOF || ch != (unsigned char) of->buf[i])
1302 break;
1303 }
1304 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1305 fclose (newfile);
1306
1307 if (no_write_p)
1308 continue;
1309 }
1310
1311 newfile = fopen (of->name, "w");
1312 if (newfile == NULL)
1313 {
1314 perror ("opening output file");
1315 exit (1);
1316 }
1317 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1318 {
1319 perror ("writing output file");
1320 exit (1);
1321 }
1322 if (fclose (newfile) != 0)
1323 {
1324 perror ("closing output file");
1325 exit (1);
1326 }
1327 }
1328 }
1329 \f
1330 struct flist {
1331 struct flist *next;
1332 int started_p;
1333 const char *name;
1334 outf_p f;
1335 };
1336
1337 struct walk_type_data;
1338
1339 /* For scalars and strings, given the item in 'val'.
1340 For structures, given a pointer to the item in 'val'.
1341 For misc. pointers, given the item in 'val'.
1342 */
1343 typedef void (*process_field_fn)
1344 (type_p f, const struct walk_type_data *p);
1345 typedef void (*func_name_fn)
1346 (type_p s, const struct walk_type_data *p);
1347
1348 /* Parameters for write_types. */
1349
1350 struct write_types_data
1351 {
1352 const char *prefix;
1353 const char *param_prefix;
1354 const char *subfield_marker_routine;
1355 const char *marker_routine;
1356 const char *reorder_note_routine;
1357 const char *comment;
1358 };
1359
1360 static void output_escaped_param (struct walk_type_data *d,
1361 const char *, const char *);
1362 static void output_mangled_typename (outf_p, type_p);
1363 static void walk_type (type_p t, struct walk_type_data *d);
1364 static void write_func_for_structure
1365 (type_p orig_s, type_p s, type_p * param,
1366 const struct write_types_data *wtd);
1367 static void write_types_process_field
1368 (type_p f, const struct walk_type_data *d);
1369 static void write_types (type_p structures,
1370 type_p param_structs,
1371 const struct write_types_data *wtd);
1372 static void write_types_local_process_field
1373 (type_p f, const struct walk_type_data *d);
1374 static void write_local_func_for_structure
1375 (type_p orig_s, type_p s, type_p * param);
1376 static void write_local (type_p structures,
1377 type_p param_structs);
1378 static void write_enum_defn (type_p structures, type_p param_structs);
1379 static int contains_scalar_p (type_p t);
1380 static void put_mangled_filename (outf_p , const char *);
1381 static void finish_root_table (struct flist *flp, const char *pfx,
1382 const char *tname, const char *lastname,
1383 const char *name);
1384 static void write_root (outf_p , pair_p, type_p, const char *, int,
1385 struct fileloc *, const char *);
1386 static void write_array (outf_p f, pair_p v,
1387 const struct write_types_data *wtd);
1388 static void write_roots (pair_p);
1389
1390 /* Parameters for walk_type. */
1391
1392 struct walk_type_data
1393 {
1394 process_field_fn process_field;
1395 const void *cookie;
1396 outf_p of;
1397 options_p opt;
1398 const char *val;
1399 const char *prev_val[4];
1400 int indent;
1401 int counter;
1402 struct fileloc *line;
1403 lang_bitmap bitmap;
1404 type_p *param;
1405 int used_length;
1406 type_p orig_s;
1407 const char *reorder_fn;
1408 bool needs_cast_p;
1409 bool fn_wants_lvalue;
1410 };
1411
1412 /* Print a mangled name representing T to OF. */
1413
1414 static void
1415 output_mangled_typename (outf_p of, type_p t)
1416 {
1417 if (t == NULL)
1418 oprintf (of, "Z");
1419 else switch (t->kind)
1420 {
1421 case TYPE_POINTER:
1422 oprintf (of, "P");
1423 output_mangled_typename (of, t->u.p);
1424 break;
1425 case TYPE_SCALAR:
1426 oprintf (of, "I");
1427 break;
1428 case TYPE_STRING:
1429 oprintf (of, "S");
1430 break;
1431 case TYPE_STRUCT:
1432 case TYPE_UNION:
1433 case TYPE_LANG_STRUCT:
1434 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1435 break;
1436 case TYPE_PARAM_STRUCT:
1437 {
1438 int i;
1439 for (i = 0; i < NUM_PARAM; i++)
1440 if (t->u.param_struct.param[i] != NULL)
1441 output_mangled_typename (of, t->u.param_struct.param[i]);
1442 output_mangled_typename (of, t->u.param_struct.stru);
1443 }
1444 break;
1445 case TYPE_ARRAY:
1446 gcc_unreachable ();
1447 }
1448 }
1449
1450 /* Print PARAM to D->OF processing escapes. D->VAL references the
1451 current object, D->PREV_VAL the object containing the current
1452 object, ONAME is the name of the option and D->LINE is used to
1453 print error messages. */
1454
1455 static void
1456 output_escaped_param (struct walk_type_data *d, const char *param,
1457 const char *oname)
1458 {
1459 const char *p;
1460
1461 for (p = param; *p; p++)
1462 if (*p != '%')
1463 oprintf (d->of, "%c", *p);
1464 else switch (*++p)
1465 {
1466 case 'h':
1467 oprintf (d->of, "(%s)", d->prev_val[2]);
1468 break;
1469 case '0':
1470 oprintf (d->of, "(%s)", d->prev_val[0]);
1471 break;
1472 case '1':
1473 oprintf (d->of, "(%s)", d->prev_val[1]);
1474 break;
1475 case 'a':
1476 {
1477 const char *pp = d->val + strlen (d->val);
1478 while (pp[-1] == ']')
1479 while (*pp != '[')
1480 pp--;
1481 oprintf (d->of, "%s", pp);
1482 }
1483 break;
1484 default:
1485 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1486 oname, '%', *p);
1487 }
1488 }
1489
1490 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1491 which is of type T. Write code to D->OF to constrain execution (at
1492 the point that D->PROCESS_FIELD is called) to the appropriate
1493 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1494 pointers to those objects. D->PREV_VAL lists the objects
1495 containing the current object, D->OPT is a list of options to
1496 apply, D->INDENT is the current indentation level, D->LINE is used
1497 to print error messages, D->BITMAP indicates which languages to
1498 print the structure for, and D->PARAM is the current parameter
1499 (from an enclosing param_is option). */
1500
1501 static void
1502 walk_type (type_p t, struct walk_type_data *d)
1503 {
1504 const char *length = NULL;
1505 const char *desc = NULL;
1506 int maybe_undef_p = 0;
1507 int use_param_num = -1;
1508 int use_params_p = 0;
1509 options_p oo;
1510 const struct nested_ptr_data *nested_ptr_d = NULL;
1511
1512 d->needs_cast_p = false;
1513 for (oo = d->opt; oo; oo = oo->next)
1514 if (strcmp (oo->name, "length") == 0)
1515 length = oo->info;
1516 else if (strcmp (oo->name, "maybe_undef") == 0)
1517 maybe_undef_p = 1;
1518 else if (strncmp (oo->name, "use_param", 9) == 0
1519 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1520 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1521 else if (strcmp (oo->name, "use_params") == 0)
1522 use_params_p = 1;
1523 else if (strcmp (oo->name, "desc") == 0)
1524 desc = oo->info;
1525 else if (strcmp (oo->name, "nested_ptr") == 0)
1526 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1527 else if (strcmp (oo->name, "dot") == 0)
1528 ;
1529 else if (strcmp (oo->name, "tag") == 0)
1530 ;
1531 else if (strcmp (oo->name, "special") == 0)
1532 ;
1533 else if (strcmp (oo->name, "skip") == 0)
1534 ;
1535 else if (strcmp (oo->name, "default") == 0)
1536 ;
1537 else if (strcmp (oo->name, "descbits") == 0)
1538 ;
1539 else if (strcmp (oo->name, "param_is") == 0)
1540 ;
1541 else if (strncmp (oo->name, "param", 5) == 0
1542 && ISDIGIT (oo->name[5])
1543 && strcmp (oo->name + 6, "_is") == 0)
1544 ;
1545 else if (strcmp (oo->name, "chain_next") == 0)
1546 ;
1547 else if (strcmp (oo->name, "chain_prev") == 0)
1548 ;
1549 else if (strcmp (oo->name, "reorder") == 0)
1550 ;
1551 else
1552 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1553
1554 if (d->used_length)
1555 length = NULL;
1556
1557 if (use_params_p)
1558 {
1559 int pointer_p = t->kind == TYPE_POINTER;
1560
1561 if (pointer_p)
1562 t = t->u.p;
1563 if (! UNION_OR_STRUCT_P (t))
1564 error_at_line (d->line, "`use_params' option on unimplemented type");
1565 else
1566 t = find_param_structure (t, d->param);
1567 if (pointer_p)
1568 t = create_pointer (t);
1569 }
1570
1571 if (use_param_num != -1)
1572 {
1573 if (d->param != NULL && d->param[use_param_num] != NULL)
1574 {
1575 type_p nt = d->param[use_param_num];
1576
1577 if (t->kind == TYPE_ARRAY)
1578 nt = create_array (nt, t->u.a.len);
1579 else if (length != NULL && t->kind == TYPE_POINTER)
1580 nt = create_pointer (nt);
1581 d->needs_cast_p = (t->kind != TYPE_POINTER
1582 && (nt->kind == TYPE_POINTER
1583 || nt->kind == TYPE_STRING));
1584 t = nt;
1585 }
1586 else
1587 error_at_line (d->line, "no parameter defined for `%s'",
1588 d->val);
1589 }
1590
1591 if (maybe_undef_p
1592 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1593 {
1594 error_at_line (d->line,
1595 "field `%s' has invalid option `maybe_undef_p'\n",
1596 d->val);
1597 return;
1598 }
1599
1600 switch (t->kind)
1601 {
1602 case TYPE_SCALAR:
1603 case TYPE_STRING:
1604 d->process_field (t, d);
1605 break;
1606
1607 case TYPE_POINTER:
1608 {
1609 if (maybe_undef_p
1610 && t->u.p->u.s.line.file == NULL)
1611 {
1612 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1613 break;
1614 }
1615
1616 if (! length)
1617 {
1618 if (! UNION_OR_STRUCT_P (t->u.p)
1619 && t->u.p->kind != TYPE_PARAM_STRUCT)
1620 {
1621 error_at_line (d->line,
1622 "field `%s' is pointer to unimplemented type",
1623 d->val);
1624 break;
1625 }
1626
1627 if (nested_ptr_d)
1628 {
1629 const char *oldprevval2 = d->prev_val[2];
1630
1631 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1632 {
1633 error_at_line (d->line,
1634 "field `%s' has invalid "
1635 "option `nested_ptr'\n",
1636 d->val);
1637 return;
1638 }
1639
1640 d->prev_val[2] = d->val;
1641 oprintf (d->of, "%*s{\n", d->indent, "");
1642 d->indent += 2;
1643 d->val = xasprintf ("x%d", d->counter++);
1644 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1645 (nested_ptr_d->type->kind == TYPE_UNION
1646 ? "union" : "struct"),
1647 nested_ptr_d->type->u.s.tag,
1648 d->fn_wants_lvalue ? "" : "const ",
1649 d->val);
1650 oprintf (d->of, "%*s", d->indent + 2, "");
1651 output_escaped_param (d, nested_ptr_d->convert_from,
1652 "nested_ptr");
1653 oprintf (d->of, ";\n");
1654
1655 d->process_field (nested_ptr_d->type, d);
1656
1657 if (d->fn_wants_lvalue)
1658 {
1659 oprintf (d->of, "%*s%s = ", d->indent, "",
1660 d->prev_val[2]);
1661 d->prev_val[2] = d->val;
1662 output_escaped_param (d, nested_ptr_d->convert_to,
1663 "nested_ptr");
1664 oprintf (d->of, ";\n");
1665 }
1666
1667 d->indent -= 2;
1668 oprintf (d->of, "%*s}\n", d->indent, "");
1669 d->val = d->prev_val[2];
1670 d->prev_val[2] = oldprevval2;
1671 }
1672 else
1673 d->process_field (t->u.p, d);
1674 }
1675 else
1676 {
1677 int loopcounter = d->counter++;
1678 const char *oldval = d->val;
1679 const char *oldprevval3 = d->prev_val[3];
1680 char *newval;
1681
1682 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1683 d->indent += 2;
1684 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1685 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1686 loopcounter, loopcounter);
1687 output_escaped_param (d, length, "length");
1688 oprintf (d->of, "); i%d++) {\n", loopcounter);
1689 d->indent += 2;
1690 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1691 d->used_length = 1;
1692 d->prev_val[3] = oldval;
1693 walk_type (t->u.p, d);
1694 free (newval);
1695 d->val = oldval;
1696 d->prev_val[3] = oldprevval3;
1697 d->used_length = 0;
1698 d->indent -= 2;
1699 oprintf (d->of, "%*s}\n", d->indent, "");
1700 d->process_field(t, d);
1701 d->indent -= 2;
1702 oprintf (d->of, "%*s}\n", d->indent, "");
1703 }
1704 }
1705 break;
1706
1707 case TYPE_ARRAY:
1708 {
1709 int loopcounter = d->counter++;
1710 const char *oldval = d->val;
1711 char *newval;
1712
1713 /* If it's an array of scalars, we optimize by not generating
1714 any code. */
1715 if (t->u.a.p->kind == TYPE_SCALAR)
1716 break;
1717
1718 oprintf (d->of, "%*s{\n", d->indent, "");
1719 d->indent += 2;
1720 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1721 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1722 loopcounter, loopcounter);
1723 if (length)
1724 output_escaped_param (d, length, "length");
1725 else
1726 oprintf (d->of, "%s", t->u.a.len);
1727 oprintf (d->of, "); i%d++) {\n", loopcounter);
1728 d->indent += 2;
1729 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1730 d->used_length = 1;
1731 walk_type (t->u.a.p, d);
1732 free (newval);
1733 d->used_length = 0;
1734 d->val = oldval;
1735 d->indent -= 2;
1736 oprintf (d->of, "%*s}\n", d->indent, "");
1737 d->indent -= 2;
1738 oprintf (d->of, "%*s}\n", d->indent, "");
1739 }
1740 break;
1741
1742 case TYPE_STRUCT:
1743 case TYPE_UNION:
1744 {
1745 pair_p f;
1746 const char *oldval = d->val;
1747 const char *oldprevval1 = d->prev_val[1];
1748 const char *oldprevval2 = d->prev_val[2];
1749 const int union_p = t->kind == TYPE_UNION;
1750 int seen_default_p = 0;
1751 options_p o;
1752
1753 if (! t->u.s.line.file)
1754 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1755
1756 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1757 {
1758 error_at_line (d->line,
1759 "structure `%s' defined for mismatching languages",
1760 t->u.s.tag);
1761 error_at_line (&t->u.s.line, "one structure defined here");
1762 }
1763
1764 /* Some things may also be defined in the structure's options. */
1765 for (o = t->u.s.opt; o; o = o->next)
1766 if (! desc && strcmp (o->name, "desc") == 0)
1767 desc = o->info;
1768
1769 d->prev_val[2] = oldval;
1770 d->prev_val[1] = oldprevval2;
1771 if (union_p)
1772 {
1773 if (desc == NULL)
1774 {
1775 error_at_line (d->line, "missing `desc' option for union `%s'",
1776 t->u.s.tag);
1777 desc = "1";
1778 }
1779 oprintf (d->of, "%*sswitch (", d->indent, "");
1780 output_escaped_param (d, desc, "desc");
1781 oprintf (d->of, ")\n");
1782 d->indent += 2;
1783 oprintf (d->of, "%*s{\n", d->indent, "");
1784 }
1785 for (f = t->u.s.fields; f; f = f->next)
1786 {
1787 options_p oo;
1788 const char *dot = ".";
1789 const char *tagid = NULL;
1790 int skip_p = 0;
1791 int default_p = 0;
1792 int use_param_p = 0;
1793 char *newval;
1794
1795 d->reorder_fn = NULL;
1796 for (oo = f->opt; oo; oo = oo->next)
1797 if (strcmp (oo->name, "dot") == 0)
1798 dot = oo->info;
1799 else if (strcmp (oo->name, "tag") == 0)
1800 tagid = oo->info;
1801 else if (strcmp (oo->name, "skip") == 0)
1802 skip_p = 1;
1803 else if (strcmp (oo->name, "default") == 0)
1804 default_p = 1;
1805 else if (strcmp (oo->name, "reorder") == 0)
1806 d->reorder_fn = oo->info;
1807 else if (strncmp (oo->name, "use_param", 9) == 0
1808 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1809 use_param_p = 1;
1810
1811 if (skip_p)
1812 continue;
1813
1814 if (union_p && tagid)
1815 {
1816 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1817 d->indent += 2;
1818 }
1819 else if (union_p && default_p)
1820 {
1821 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1822 d->indent += 2;
1823 seen_default_p = 1;
1824 }
1825 else if (! union_p && (default_p || tagid))
1826 error_at_line (d->line,
1827 "can't use `%s' outside a union on field `%s'",
1828 default_p ? "default" : "tag", f->name);
1829 else if (union_p && ! (default_p || tagid)
1830 && f->type->kind == TYPE_SCALAR)
1831 {
1832 fprintf (stderr,
1833 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1834 d->line->file, d->line->line, f->name);
1835 continue;
1836 }
1837 else if (union_p && ! (default_p || tagid))
1838 error_at_line (d->line,
1839 "field `%s' is missing `tag' or `default' option",
1840 f->name);
1841
1842 d->line = &f->line;
1843 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1844 d->opt = f->opt;
1845 d->used_length = false;
1846
1847 if (union_p && use_param_p && d->param == NULL)
1848 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1849 else
1850 walk_type (f->type, d);
1851
1852 free (newval);
1853
1854 if (union_p)
1855 {
1856 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1857 d->indent -= 2;
1858 }
1859 }
1860 d->reorder_fn = NULL;
1861
1862 d->val = oldval;
1863 d->prev_val[1] = oldprevval1;
1864 d->prev_val[2] = oldprevval2;
1865
1866 if (union_p && ! seen_default_p)
1867 {
1868 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1869 oprintf (d->of, "%*s break;\n", d->indent, "");
1870 }
1871 if (union_p)
1872 {
1873 oprintf (d->of, "%*s}\n", d->indent, "");
1874 d->indent -= 2;
1875 }
1876 }
1877 break;
1878
1879 case TYPE_LANG_STRUCT:
1880 {
1881 type_p nt;
1882 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1883 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1884 break;
1885 if (nt == NULL)
1886 error_at_line (d->line, "structure `%s' differs between languages",
1887 t->u.s.tag);
1888 else
1889 walk_type (nt, d);
1890 }
1891 break;
1892
1893 case TYPE_PARAM_STRUCT:
1894 {
1895 type_p *oldparam = d->param;
1896
1897 d->param = t->u.param_struct.param;
1898 walk_type (t->u.param_struct.stru, d);
1899 d->param = oldparam;
1900 }
1901 break;
1902
1903 default:
1904 gcc_unreachable ();
1905 }
1906 }
1907
1908 /* process_field routine for marking routines. */
1909
1910 static void
1911 write_types_process_field (type_p f, const struct walk_type_data *d)
1912 {
1913 const struct write_types_data *wtd;
1914 const char *cast = d->needs_cast_p ? "(void *)" : "";
1915 wtd = (const struct write_types_data *) d->cookie;
1916
1917 switch (f->kind)
1918 {
1919 case TYPE_POINTER:
1920 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1921 wtd->subfield_marker_routine, cast, d->val);
1922 if (wtd->param_prefix)
1923 {
1924 oprintf (d->of, ", %s", d->prev_val[3]);
1925 if (d->orig_s)
1926 {
1927 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1928 output_mangled_typename (d->of, d->orig_s);
1929 }
1930 else
1931 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1932
1933 if (f->u.p->kind == TYPE_PARAM_STRUCT
1934 && f->u.p->u.s.line.file != NULL)
1935 {
1936 oprintf (d->of, ", gt_e_");
1937 output_mangled_typename (d->of, f);
1938 }
1939 else if (UNION_OR_STRUCT_P (f)
1940 && f->u.p->u.s.line.file != NULL)
1941 {
1942 oprintf (d->of, ", gt_ggc_e_");
1943 output_mangled_typename (d->of, f);
1944 }
1945 else
1946 oprintf (d->of, ", gt_types_enum_last");
1947 }
1948 oprintf (d->of, ");\n");
1949 if (d->reorder_fn && wtd->reorder_note_routine)
1950 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1951 wtd->reorder_note_routine, cast, d->val,
1952 d->prev_val[3], d->reorder_fn);
1953 break;
1954
1955 case TYPE_STRING:
1956 if (wtd->param_prefix == NULL)
1957 break;
1958
1959 case TYPE_STRUCT:
1960 case TYPE_UNION:
1961 case TYPE_LANG_STRUCT:
1962 case TYPE_PARAM_STRUCT:
1963 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1964 output_mangled_typename (d->of, f);
1965 oprintf (d->of, " (%s%s);\n", cast, d->val);
1966 if (d->reorder_fn && wtd->reorder_note_routine)
1967 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1968 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1969 d->reorder_fn);
1970 break;
1971
1972 case TYPE_SCALAR:
1973 break;
1974
1975 default:
1976 gcc_unreachable ();
1977 }
1978 }
1979
1980 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
1981
1982 static void
1983 output_type_enum (outf_p of, type_p s)
1984 {
1985 if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
1986 {
1987 oprintf (of, ", gt_e_");
1988 output_mangled_typename (of, s);
1989 }
1990 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
1991 {
1992 oprintf (of, ", gt_ggc_e_");
1993 output_mangled_typename (of, s);
1994 }
1995 else
1996 oprintf (of, ", gt_types_enum_last");
1997 }
1998
1999 /* For S, a structure that's part of ORIG_S, and using parameters
2000 PARAM, write out a routine that:
2001 - Takes a parameter, a void * but actually of type *S
2002 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2003 field of S or its substructures and (in some cases) things
2004 that are pointed to by S.
2005 */
2006
2007 static void
2008 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2009 const struct write_types_data *wtd)
2010 {
2011 const char *fn = s->u.s.line.file;
2012 int i;
2013 const char *chain_next = NULL;
2014 const char *chain_prev = NULL;
2015 options_p opt;
2016 struct walk_type_data d;
2017
2018 /* This is a hack, and not the good kind either. */
2019 for (i = NUM_PARAM - 1; i >= 0; i--)
2020 if (param && param[i] && param[i]->kind == TYPE_POINTER
2021 && UNION_OR_STRUCT_P (param[i]->u.p))
2022 fn = param[i]->u.p->u.s.line.file;
2023
2024 memset (&d, 0, sizeof (d));
2025 d.of = get_output_file_with_visibility (fn);
2026
2027 for (opt = s->u.s.opt; opt; opt = opt->next)
2028 if (strcmp (opt->name, "chain_next") == 0)
2029 chain_next = opt->info;
2030 else if (strcmp (opt->name, "chain_prev") == 0)
2031 chain_prev = opt->info;
2032
2033 if (chain_prev != NULL && chain_next == NULL)
2034 error_at_line (&s->u.s.line, "chain_prev without chain_next");
2035
2036 d.process_field = write_types_process_field;
2037 d.cookie = wtd;
2038 d.orig_s = orig_s;
2039 d.opt = s->u.s.opt;
2040 d.line = &s->u.s.line;
2041 d.bitmap = s->u.s.bitmap;
2042 d.param = param;
2043 d.prev_val[0] = "*x";
2044 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2045 d.prev_val[3] = "x";
2046 d.val = "(*x)";
2047
2048 oprintf (d.of, "\n");
2049 oprintf (d.of, "void\n");
2050 if (param == NULL)
2051 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2052 else
2053 {
2054 oprintf (d.of, "gt_%s_", wtd->prefix);
2055 output_mangled_typename (d.of, orig_s);
2056 }
2057 oprintf (d.of, " (void *x_p)\n");
2058 oprintf (d.of, "{\n");
2059 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2060 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2061 chain_next == NULL ? "const " : "",
2062 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2063 if (chain_next != NULL)
2064 oprintf (d.of, " %s %s * xlimit = x;\n",
2065 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2066 if (chain_next == NULL)
2067 {
2068 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2069 if (wtd->param_prefix)
2070 {
2071 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2072 output_mangled_typename (d.of, orig_s);
2073 output_type_enum (d.of, orig_s);
2074 }
2075 oprintf (d.of, "))\n");
2076 }
2077 else
2078 {
2079 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2080 if (wtd->param_prefix)
2081 {
2082 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2083 output_mangled_typename (d.of, orig_s);
2084 output_type_enum (d.of, orig_s);
2085 }
2086 oprintf (d.of, "))\n");
2087 oprintf (d.of, " xlimit = (");
2088 d.prev_val[2] = "*xlimit";
2089 output_escaped_param (&d, chain_next, "chain_next");
2090 oprintf (d.of, ");\n");
2091 if (chain_prev != NULL)
2092 {
2093 oprintf (d.of, " if (x != xlimit)\n");
2094 oprintf (d.of, " for (;;)\n");
2095 oprintf (d.of, " {\n");
2096 oprintf (d.of, " %s %s * const xprev = (",
2097 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2098
2099 d.prev_val[2] = "*x";
2100 output_escaped_param (&d, chain_prev, "chain_prev");
2101 oprintf (d.of, ");\n");
2102 oprintf (d.of, " if (xprev == NULL) break;\n");
2103 oprintf (d.of, " x = xprev;\n");
2104 oprintf (d.of, " (void) %s (xprev",
2105 wtd->marker_routine);
2106 if (wtd->param_prefix)
2107 {
2108 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2109 output_mangled_typename (d.of, orig_s);
2110 output_type_enum (d.of, orig_s);
2111 }
2112 oprintf (d.of, ");\n");
2113 oprintf (d.of, " }\n");
2114 }
2115 oprintf (d.of, " while (x != xlimit)\n");
2116 }
2117 oprintf (d.of, " {\n");
2118
2119 d.prev_val[2] = "*x";
2120 d.indent = 6;
2121 walk_type (s, &d);
2122
2123 if (chain_next != NULL)
2124 {
2125 oprintf (d.of, " x = (");
2126 output_escaped_param (&d, chain_next, "chain_next");
2127 oprintf (d.of, ");\n");
2128 }
2129
2130 oprintf (d.of, " }\n");
2131 oprintf (d.of, "}\n");
2132 }
2133
2134 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2135
2136 static void
2137 write_types (type_p structures, type_p param_structs,
2138 const struct write_types_data *wtd)
2139 {
2140 type_p s;
2141
2142 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2143 for (s = structures; s; s = s->next)
2144 if (s->gc_used == GC_POINTED_TO
2145 || s->gc_used == GC_MAYBE_POINTED_TO)
2146 {
2147 options_p opt;
2148
2149 if (s->gc_used == GC_MAYBE_POINTED_TO
2150 && s->u.s.line.file == NULL)
2151 continue;
2152
2153 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2154 output_mangled_typename (header_file, s);
2155 oprintf (header_file, "(X) do { \\\n");
2156 oprintf (header_file,
2157 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2158 s->u.s.tag);
2159 oprintf (header_file,
2160 " } while (0)\n");
2161
2162 for (opt = s->u.s.opt; opt; opt = opt->next)
2163 if (strcmp (opt->name, "ptr_alias") == 0)
2164 {
2165 type_p t = (type_p) opt->info;
2166 if (t->kind == TYPE_STRUCT
2167 || t->kind == TYPE_UNION
2168 || t->kind == TYPE_LANG_STRUCT)
2169 oprintf (header_file,
2170 "#define gt_%sx_%s gt_%sx_%s\n",
2171 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2172 else
2173 error_at_line (&s->u.s.line,
2174 "structure alias is not a structure");
2175 break;
2176 }
2177 if (opt)
2178 continue;
2179
2180 /* Declare the marker procedure only once. */
2181 oprintf (header_file,
2182 "extern void gt_%sx_%s (void *);\n",
2183 wtd->prefix, s->u.s.tag);
2184
2185 if (s->u.s.line.file == NULL)
2186 {
2187 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2188 s->u.s.tag);
2189 continue;
2190 }
2191
2192 if (s->kind == TYPE_LANG_STRUCT)
2193 {
2194 type_p ss;
2195 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2196 write_func_for_structure (s, ss, NULL, wtd);
2197 }
2198 else
2199 write_func_for_structure (s, s, NULL, wtd);
2200 }
2201
2202 for (s = param_structs; s; s = s->next)
2203 if (s->gc_used == GC_POINTED_TO)
2204 {
2205 type_p * param = s->u.param_struct.param;
2206 type_p stru = s->u.param_struct.stru;
2207
2208 /* Declare the marker procedure. */
2209 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2210 output_mangled_typename (header_file, s);
2211 oprintf (header_file, " (void *);\n");
2212
2213 if (stru->u.s.line.file == NULL)
2214 {
2215 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2216 s->u.s.tag);
2217 continue;
2218 }
2219
2220 if (stru->kind == TYPE_LANG_STRUCT)
2221 {
2222 type_p ss;
2223 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2224 write_func_for_structure (s, ss, param, wtd);
2225 }
2226 else
2227 write_func_for_structure (s, stru, param, wtd);
2228 }
2229 }
2230
2231 static const struct write_types_data ggc_wtd =
2232 {
2233 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2234 "GC marker procedures. "
2235 };
2236
2237 static const struct write_types_data pch_wtd =
2238 {
2239 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2240 "gt_pch_note_reorder",
2241 "PCH type-walking procedures. "
2242 };
2243
2244 /* Write out the local pointer-walking routines. */
2245
2246 /* process_field routine for local pointer-walking. */
2247
2248 static void
2249 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2250 {
2251 switch (f->kind)
2252 {
2253 case TYPE_POINTER:
2254 case TYPE_STRUCT:
2255 case TYPE_UNION:
2256 case TYPE_LANG_STRUCT:
2257 case TYPE_PARAM_STRUCT:
2258 case TYPE_STRING:
2259 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2260 d->prev_val[3]);
2261 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2262 break;
2263
2264 case TYPE_SCALAR:
2265 break;
2266
2267 default:
2268 gcc_unreachable ();
2269 }
2270 }
2271
2272 /* For S, a structure that's part of ORIG_S, and using parameters
2273 PARAM, write out a routine that:
2274 - Is of type gt_note_pointers
2275 - Calls PROCESS_FIELD on each field of S or its substructures.
2276 */
2277
2278 static void
2279 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2280 {
2281 const char *fn = s->u.s.line.file;
2282 int i;
2283 struct walk_type_data d;
2284
2285 /* This is a hack, and not the good kind either. */
2286 for (i = NUM_PARAM - 1; i >= 0; i--)
2287 if (param && param[i] && param[i]->kind == TYPE_POINTER
2288 && UNION_OR_STRUCT_P (param[i]->u.p))
2289 fn = param[i]->u.p->u.s.line.file;
2290
2291 memset (&d, 0, sizeof (d));
2292 d.of = get_output_file_with_visibility (fn);
2293
2294 d.process_field = write_types_local_process_field;
2295 d.opt = s->u.s.opt;
2296 d.line = &s->u.s.line;
2297 d.bitmap = s->u.s.bitmap;
2298 d.param = param;
2299 d.prev_val[0] = d.prev_val[2] = "*x";
2300 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2301 d.prev_val[3] = "x";
2302 d.val = "(*x)";
2303 d.fn_wants_lvalue = true;
2304
2305 oprintf (d.of, "\n");
2306 oprintf (d.of, "void\n");
2307 oprintf (d.of, "gt_pch_p_");
2308 output_mangled_typename (d.of, orig_s);
2309 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2310 "\tvoid *x_p,\n"
2311 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2312 "\tATTRIBUTE_UNUSED void *cookie)\n");
2313 oprintf (d.of, "{\n");
2314 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2315 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2316 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2317 d.indent = 2;
2318 walk_type (s, &d);
2319 oprintf (d.of, "}\n");
2320 }
2321
2322 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2323
2324 static void
2325 write_local (type_p structures, type_p param_structs)
2326 {
2327 type_p s;
2328
2329 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2330 for (s = structures; s; s = s->next)
2331 if (s->gc_used == GC_POINTED_TO
2332 || s->gc_used == GC_MAYBE_POINTED_TO)
2333 {
2334 options_p opt;
2335
2336 if (s->u.s.line.file == NULL)
2337 continue;
2338
2339 for (opt = s->u.s.opt; opt; opt = opt->next)
2340 if (strcmp (opt->name, "ptr_alias") == 0)
2341 {
2342 type_p t = (type_p) opt->info;
2343 if (t->kind == TYPE_STRUCT
2344 || t->kind == TYPE_UNION
2345 || t->kind == TYPE_LANG_STRUCT)
2346 {
2347 oprintf (header_file, "#define gt_pch_p_");
2348 output_mangled_typename (header_file, s);
2349 oprintf (header_file, " gt_pch_p_");
2350 output_mangled_typename (header_file, t);
2351 oprintf (header_file, "\n");
2352 }
2353 else
2354 error_at_line (&s->u.s.line,
2355 "structure alias is not a structure");
2356 break;
2357 }
2358 if (opt)
2359 continue;
2360
2361 /* Declare the marker procedure only once. */
2362 oprintf (header_file, "extern void gt_pch_p_");
2363 output_mangled_typename (header_file, s);
2364 oprintf (header_file,
2365 "\n (void *, void *, gt_pointer_operator, void *);\n");
2366
2367 if (s->kind == TYPE_LANG_STRUCT)
2368 {
2369 type_p ss;
2370 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2371 write_local_func_for_structure (s, ss, NULL);
2372 }
2373 else
2374 write_local_func_for_structure (s, s, NULL);
2375 }
2376
2377 for (s = param_structs; s; s = s->next)
2378 if (s->gc_used == GC_POINTED_TO)
2379 {
2380 type_p * param = s->u.param_struct.param;
2381 type_p stru = s->u.param_struct.stru;
2382
2383 /* Declare the marker procedure. */
2384 oprintf (header_file, "extern void gt_pch_p_");
2385 output_mangled_typename (header_file, s);
2386 oprintf (header_file,
2387 "\n (void *, void *, gt_pointer_operator, void *);\n");
2388
2389 if (stru->u.s.line.file == NULL)
2390 {
2391 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2392 s->u.s.tag);
2393 continue;
2394 }
2395
2396 if (stru->kind == TYPE_LANG_STRUCT)
2397 {
2398 type_p ss;
2399 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2400 write_local_func_for_structure (s, ss, param);
2401 }
2402 else
2403 write_local_func_for_structure (s, stru, param);
2404 }
2405 }
2406
2407 /* Write out the 'enum' definition for gt_types_enum. */
2408
2409 static void
2410 write_enum_defn (type_p structures, type_p param_structs)
2411 {
2412 type_p s;
2413
2414 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2415 oprintf (header_file, "enum gt_types_enum {\n");
2416 for (s = structures; s; s = s->next)
2417 if (s->gc_used == GC_POINTED_TO
2418 || s->gc_used == GC_MAYBE_POINTED_TO)
2419 {
2420 if (s->gc_used == GC_MAYBE_POINTED_TO
2421 && s->u.s.line.file == NULL)
2422 continue;
2423
2424 oprintf (header_file, " gt_ggc_e_");
2425 output_mangled_typename (header_file, s);
2426 oprintf (header_file, ", \n");
2427 }
2428 for (s = param_structs; s; s = s->next)
2429 if (s->gc_used == GC_POINTED_TO)
2430 {
2431 oprintf (header_file, " gt_e_");
2432 output_mangled_typename (header_file, s);
2433 oprintf (header_file, ", \n");
2434 }
2435 oprintf (header_file, " gt_types_enum_last\n");
2436 oprintf (header_file, "};\n");
2437 }
2438
2439 /* Might T contain any non-pointer elements? */
2440
2441 static int
2442 contains_scalar_p (type_p t)
2443 {
2444 switch (t->kind)
2445 {
2446 case TYPE_STRING:
2447 case TYPE_POINTER:
2448 return 0;
2449 case TYPE_ARRAY:
2450 return contains_scalar_p (t->u.a.p);
2451 default:
2452 /* Could also check for structures that have no non-pointer
2453 fields, but there aren't enough of those to worry about. */
2454 return 1;
2455 }
2456 }
2457
2458 /* Mangle FN and print it to F. */
2459
2460 static void
2461 put_mangled_filename (outf_p f, const char *fn)
2462 {
2463 const char *name = get_output_file_name (fn);
2464 for (; *name != 0; name++)
2465 if (ISALNUM (*name))
2466 oprintf (f, "%c", *name);
2467 else
2468 oprintf (f, "%c", '_');
2469 }
2470
2471 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2472 LASTNAME, and NAME are all strings to insert in various places in
2473 the resulting code. */
2474
2475 static void
2476 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2477 const char *tname, const char *name)
2478 {
2479 struct flist *fli2;
2480
2481 for (fli2 = flp; fli2; fli2 = fli2->next)
2482 if (fli2->started_p)
2483 {
2484 oprintf (fli2->f, " %s\n", lastname);
2485 oprintf (fli2->f, "};\n\n");
2486 }
2487
2488 for (fli2 = flp; fli2; fli2 = fli2->next)
2489 if (fli2->started_p)
2490 {
2491 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2492 int fnum;
2493
2494 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2495 if (bitmap & 1)
2496 {
2497 oprintf (base_files[fnum],
2498 "extern const struct %s gt_%s_",
2499 tname, pfx);
2500 put_mangled_filename (base_files[fnum], fli2->name);
2501 oprintf (base_files[fnum], "[];\n");
2502 }
2503 }
2504
2505 {
2506 size_t fnum;
2507 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2508 oprintf (base_files [fnum],
2509 "const struct %s * const %s[] = {\n",
2510 tname, name);
2511 }
2512
2513
2514 for (fli2 = flp; fli2; fli2 = fli2->next)
2515 if (fli2->started_p)
2516 {
2517 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2518 int fnum;
2519
2520 fli2->started_p = 0;
2521
2522 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2523 if (bitmap & 1)
2524 {
2525 oprintf (base_files[fnum], " gt_%s_", pfx);
2526 put_mangled_filename (base_files[fnum], fli2->name);
2527 oprintf (base_files[fnum], ",\n");
2528 }
2529 }
2530
2531 {
2532 size_t fnum;
2533 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2534 {
2535 oprintf (base_files[fnum], " NULL\n");
2536 oprintf (base_files[fnum], "};\n");
2537 }
2538 }
2539 }
2540
2541 /* Write out to F the table entry and any marker routines needed to
2542 mark NAME as TYPE. The original variable is V, at LINE.
2543 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2544 is nonzero iff we are building the root table for hash table caches. */
2545
2546 static void
2547 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2548 struct fileloc *line, const char *if_marked)
2549 {
2550 switch (type->kind)
2551 {
2552 case TYPE_STRUCT:
2553 {
2554 pair_p fld;
2555 for (fld = type->u.s.fields; fld; fld = fld->next)
2556 {
2557 int skip_p = 0;
2558 const char *desc = NULL;
2559 options_p o;
2560
2561 for (o = fld->opt; o; o = o->next)
2562 if (strcmp (o->name, "skip") == 0)
2563 skip_p = 1;
2564 else if (strcmp (o->name, "desc") == 0)
2565 desc = o->info;
2566 else
2567 error_at_line (line,
2568 "field `%s' of global `%s' has unknown option `%s'",
2569 fld->name, name, o->name);
2570
2571 if (skip_p)
2572 continue;
2573 else if (desc && fld->type->kind == TYPE_UNION)
2574 {
2575 pair_p validf = NULL;
2576 pair_p ufld;
2577
2578 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2579 {
2580 const char *tag = NULL;
2581 options_p oo;
2582
2583 for (oo = ufld->opt; oo; oo = oo->next)
2584 if (strcmp (oo->name, "tag") == 0)
2585 tag = oo->info;
2586 if (tag == NULL || strcmp (tag, desc) != 0)
2587 continue;
2588 if (validf != NULL)
2589 error_at_line (line,
2590 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2591 name, fld->name, validf->name,
2592 name, fld->name, ufld->name,
2593 tag);
2594 validf = ufld;
2595 }
2596 if (validf != NULL)
2597 {
2598 char *newname;
2599 newname = xasprintf ("%s.%s.%s",
2600 name, fld->name, validf->name);
2601 write_root (f, v, validf->type, newname, 0, line,
2602 if_marked);
2603 free (newname);
2604 }
2605 }
2606 else if (desc)
2607 error_at_line (line,
2608 "global `%s.%s' has `desc' option but is not union",
2609 name, fld->name);
2610 else
2611 {
2612 char *newname;
2613 newname = xasprintf ("%s.%s", name, fld->name);
2614 write_root (f, v, fld->type, newname, 0, line, if_marked);
2615 free (newname);
2616 }
2617 }
2618 }
2619 break;
2620
2621 case TYPE_ARRAY:
2622 {
2623 char *newname;
2624 newname = xasprintf ("%s[0]", name);
2625 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2626 free (newname);
2627 }
2628 break;
2629
2630 case TYPE_POINTER:
2631 {
2632 type_p ap, tp;
2633
2634 oprintf (f, " {\n");
2635 oprintf (f, " &%s,\n", name);
2636 oprintf (f, " 1");
2637
2638 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2639 if (ap->u.a.len[0])
2640 oprintf (f, " * (%s)", ap->u.a.len);
2641 else if (ap == v->type)
2642 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2643 oprintf (f, ",\n");
2644 oprintf (f, " sizeof (%s", v->name);
2645 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2646 oprintf (f, "[0]");
2647 oprintf (f, "),\n");
2648
2649 tp = type->u.p;
2650
2651 if (! has_length && UNION_OR_STRUCT_P (tp))
2652 {
2653 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2654 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2655 }
2656 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2657 {
2658 oprintf (f, " &gt_ggc_m_");
2659 output_mangled_typename (f, tp);
2660 oprintf (f, ",\n &gt_pch_n_");
2661 output_mangled_typename (f, tp);
2662 }
2663 else if (has_length
2664 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2665 {
2666 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2667 oprintf (f, " &gt_pch_na_%s", name);
2668 }
2669 else
2670 {
2671 error_at_line (line,
2672 "global `%s' is pointer to unimplemented type",
2673 name);
2674 }
2675 if (if_marked)
2676 oprintf (f, ",\n &%s", if_marked);
2677 oprintf (f, "\n },\n");
2678 }
2679 break;
2680
2681 case TYPE_STRING:
2682 {
2683 oprintf (f, " {\n");
2684 oprintf (f, " &%s,\n", name);
2685 oprintf (f, " 1, \n");
2686 oprintf (f, " sizeof (%s),\n", v->name);
2687 oprintf (f, " &gt_ggc_m_S,\n");
2688 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2689 oprintf (f, " },\n");
2690 }
2691 break;
2692
2693 case TYPE_SCALAR:
2694 break;
2695
2696 default:
2697 error_at_line (line,
2698 "global `%s' is unimplemented type",
2699 name);
2700 }
2701 }
2702
2703 /* This generates a routine to walk an array. */
2704
2705 static void
2706 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2707 {
2708 struct walk_type_data d;
2709 char *prevval3;
2710
2711 memset (&d, 0, sizeof (d));
2712 d.of = f;
2713 d.cookie = wtd;
2714 d.indent = 2;
2715 d.line = &v->line;
2716 d.opt = v->opt;
2717 d.bitmap = get_base_file_bitmap (v->line.file);
2718 d.param = NULL;
2719
2720 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2721
2722 if (wtd->param_prefix)
2723 {
2724 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2725 oprintf (f,
2726 " (void *, void *, gt_pointer_operator, void *);\n");
2727 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2728 wtd->param_prefix, v->name);
2729 oprintf (d.of,
2730 " ATTRIBUTE_UNUSED void *x_p,\n"
2731 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2732 " ATTRIBUTE_UNUSED void * cookie)\n");
2733 oprintf (d.of, "{\n");
2734 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2735 d.process_field = write_types_local_process_field;
2736 walk_type (v->type, &d);
2737 oprintf (f, "}\n\n");
2738 }
2739
2740 d.opt = v->opt;
2741 oprintf (f, "static void gt_%sa_%s (void *);\n",
2742 wtd->prefix, v->name);
2743 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2744 wtd->prefix, v->name);
2745 oprintf (f, "{\n");
2746 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2747 d.process_field = write_types_process_field;
2748 walk_type (v->type, &d);
2749 free (prevval3);
2750 oprintf (f, "}\n\n");
2751 }
2752
2753 /* Output a table describing the locations and types of VARIABLES. */
2754
2755 static void
2756 write_roots (pair_p variables)
2757 {
2758 pair_p v;
2759 struct flist *flp = NULL;
2760
2761 for (v = variables; v; v = v->next)
2762 {
2763 outf_p f = get_output_file_with_visibility (v->line.file);
2764 struct flist *fli;
2765 const char *length = NULL;
2766 int deletable_p = 0;
2767 options_p o;
2768
2769 for (o = v->opt; o; o = o->next)
2770 if (strcmp (o->name, "length") == 0)
2771 length = o->info;
2772 else if (strcmp (o->name, "deletable") == 0)
2773 deletable_p = 1;
2774 else if (strcmp (o->name, "param_is") == 0)
2775 ;
2776 else if (strncmp (o->name, "param", 5) == 0
2777 && ISDIGIT (o->name[5])
2778 && strcmp (o->name + 6, "_is") == 0)
2779 ;
2780 else if (strcmp (o->name, "if_marked") == 0)
2781 ;
2782 else
2783 error_at_line (&v->line,
2784 "global `%s' has unknown option `%s'",
2785 v->name, o->name);
2786
2787 for (fli = flp; fli; fli = fli->next)
2788 if (fli->f == f)
2789 break;
2790 if (fli == NULL)
2791 {
2792 fli = XNEW (struct flist);
2793 fli->f = f;
2794 fli->next = flp;
2795 fli->started_p = 0;
2796 fli->name = v->line.file;
2797 flp = fli;
2798
2799 oprintf (f, "\n/* GC roots. */\n\n");
2800 }
2801
2802 if (! deletable_p
2803 && length
2804 && v->type->kind == TYPE_POINTER
2805 && (v->type->u.p->kind == TYPE_POINTER
2806 || v->type->u.p->kind == TYPE_STRUCT))
2807 {
2808 write_array (f, v, &ggc_wtd);
2809 write_array (f, v, &pch_wtd);
2810 }
2811 }
2812
2813 for (v = variables; v; v = v->next)
2814 {
2815 outf_p f = get_output_file_with_visibility (v->line.file);
2816 struct flist *fli;
2817 int skip_p = 0;
2818 int length_p = 0;
2819 options_p o;
2820
2821 for (o = v->opt; o; o = o->next)
2822 if (strcmp (o->name, "length") == 0)
2823 length_p = 1;
2824 else if (strcmp (o->name, "deletable") == 0
2825 || strcmp (o->name, "if_marked") == 0)
2826 skip_p = 1;
2827
2828 if (skip_p)
2829 continue;
2830
2831 for (fli = flp; fli; fli = fli->next)
2832 if (fli->f == f)
2833 break;
2834 if (! fli->started_p)
2835 {
2836 fli->started_p = 1;
2837
2838 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2839 put_mangled_filename (f, v->line.file);
2840 oprintf (f, "[] = {\n");
2841 }
2842
2843 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2844 }
2845
2846 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2847 "gt_ggc_rtab");
2848
2849 for (v = variables; v; v = v->next)
2850 {
2851 outf_p f = get_output_file_with_visibility (v->line.file);
2852 struct flist *fli;
2853 int skip_p = 1;
2854 options_p o;
2855
2856 for (o = v->opt; o; o = o->next)
2857 if (strcmp (o->name, "deletable") == 0)
2858 skip_p = 0;
2859 else if (strcmp (o->name, "if_marked") == 0)
2860 skip_p = 1;
2861
2862 if (skip_p)
2863 continue;
2864
2865 for (fli = flp; fli; fli = fli->next)
2866 if (fli->f == f)
2867 break;
2868 if (! fli->started_p)
2869 {
2870 fli->started_p = 1;
2871
2872 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2873 put_mangled_filename (f, v->line.file);
2874 oprintf (f, "[] = {\n");
2875 }
2876
2877 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2878 v->name, v->name);
2879 }
2880
2881 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2882 "gt_ggc_deletable_rtab");
2883
2884 for (v = variables; v; v = v->next)
2885 {
2886 outf_p f = get_output_file_with_visibility (v->line.file);
2887 struct flist *fli;
2888 const char *if_marked = NULL;
2889 int length_p = 0;
2890 options_p o;
2891
2892 for (o = v->opt; o; o = o->next)
2893 if (strcmp (o->name, "length") == 0)
2894 length_p = 1;
2895 else if (strcmp (o->name, "if_marked") == 0)
2896 if_marked = o->info;
2897
2898 if (if_marked == NULL)
2899 continue;
2900
2901 if (v->type->kind != TYPE_POINTER
2902 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2903 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2904 {
2905 error_at_line (&v->line, "if_marked option used but not hash table");
2906 continue;
2907 }
2908
2909 for (fli = flp; fli; fli = fli->next)
2910 if (fli->f == f)
2911 break;
2912 if (! fli->started_p)
2913 {
2914 fli->started_p = 1;
2915
2916 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2917 put_mangled_filename (f, v->line.file);
2918 oprintf (f, "[] = {\n");
2919 }
2920
2921 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2922 v->name, length_p, &v->line, if_marked);
2923 }
2924
2925 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2926 "gt_ggc_cache_rtab");
2927
2928 for (v = variables; v; v = v->next)
2929 {
2930 outf_p f = get_output_file_with_visibility (v->line.file);
2931 struct flist *fli;
2932 int length_p = 0;
2933 int if_marked_p = 0;
2934 options_p o;
2935
2936 for (o = v->opt; o; o = o->next)
2937 if (strcmp (o->name, "length") == 0)
2938 length_p = 1;
2939 else if (strcmp (o->name, "if_marked") == 0)
2940 if_marked_p = 1;
2941
2942 if (! if_marked_p)
2943 continue;
2944
2945 for (fli = flp; fli; fli = fli->next)
2946 if (fli->f == f)
2947 break;
2948 if (! fli->started_p)
2949 {
2950 fli->started_p = 1;
2951
2952 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2953 put_mangled_filename (f, v->line.file);
2954 oprintf (f, "[] = {\n");
2955 }
2956
2957 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2958 }
2959
2960 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2961 "gt_pch_cache_rtab");
2962
2963 for (v = variables; v; v = v->next)
2964 {
2965 outf_p f = get_output_file_with_visibility (v->line.file);
2966 struct flist *fli;
2967 int skip_p = 0;
2968 options_p o;
2969
2970 for (o = v->opt; o; o = o->next)
2971 if (strcmp (o->name, "deletable") == 0
2972 || strcmp (o->name, "if_marked") == 0)
2973 skip_p = 1;
2974
2975 if (skip_p)
2976 continue;
2977
2978 if (! contains_scalar_p (v->type))
2979 continue;
2980
2981 for (fli = flp; fli; fli = fli->next)
2982 if (fli->f == f)
2983 break;
2984 if (! fli->started_p)
2985 {
2986 fli->started_p = 1;
2987
2988 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2989 put_mangled_filename (f, v->line.file);
2990 oprintf (f, "[] = {\n");
2991 }
2992
2993 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2994 v->name, v->name);
2995 }
2996
2997 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2998 "gt_pch_scalar_rtab");
2999 }
3000
3001 \f
3002 extern int main (int argc, char **argv);
3003 int
3004 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
3005 {
3006 unsigned i;
3007 static struct fileloc pos = { __FILE__, __LINE__ };
3008 unsigned j;
3009
3010 gen_rtx_next ();
3011
3012 srcdir_len = strlen (srcdir);
3013
3014 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3015 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3016 do_scalar_typedef ("uint8", &pos);
3017 do_scalar_typedef ("jword", &pos);
3018 do_scalar_typedef ("JCF_u2", &pos);
3019 #ifdef USE_MAPPED_LOCATION
3020 do_scalar_typedef ("location_t", &pos);
3021 do_scalar_typedef ("source_locus", &pos);
3022 #endif
3023 do_scalar_typedef ("void", &pos);
3024
3025 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3026
3027 do_typedef ("HARD_REG_SET", create_array (
3028 create_scalar_type ("unsigned long", strlen ("unsigned long")),
3029 "2"), &pos);
3030
3031 for (i = 0; i < NUM_GT_FILES; i++)
3032 {
3033 int dupflag = 0;
3034 /* Omit if already seen. */
3035 for (j = 0; j < i; j++)
3036 {
3037 if (!strcmp (all_files[i], all_files[j]))
3038 {
3039 dupflag = 1;
3040 break;
3041 }
3042 }
3043 if (!dupflag)
3044 parse_file (all_files[i]);
3045 #ifndef USE_MAPPED_LOCATION
3046 /* temporary kludge - gengtype doesn't handle conditionals.
3047 Manually add source_locus *after* we've processed input.h. */
3048 if (i == 0)
3049 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3050 #endif
3051 }
3052
3053 if (hit_error != 0)
3054 exit (1);
3055
3056 set_gc_used (variables);
3057
3058 open_base_files ();
3059 write_enum_defn (structures, param_structs);
3060 write_types (structures, param_structs, &ggc_wtd);
3061 write_types (structures, param_structs, &pch_wtd);
3062 write_local (structures, param_structs);
3063 write_roots (variables);
3064 write_rtx_next ();
3065 close_output_files ();
3066
3067 return (hit_error != 0);
3068 }