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