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