OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [gengtype.c] - Blame information for rev 12

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.