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