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