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