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