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