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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [gengtype.c] - Blame information for rev 823

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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