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