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