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