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