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