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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [gengtype.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* Process source files and output type information.
2
   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GCC.
6
 
7
   GCC is free software; you can redistribute it and/or modify it under
8
   the terms of the GNU General Public License as published by the Free
9
   Software Foundation; either version 3, or (at your option) any later
10
   version.
11
 
12
   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
   WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
   for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with GCC; see the file COPYING3.  If not see
19
   <http://www.gnu.org/licenses/>.  */
20
 
21
#ifdef GENERATOR_FILE
22
#include "bconfig.h"
23
#else
24
#include "config.h"
25
#endif
26
#include "system.h"
27
#include "errors.h"             /* for fatal */
28
#include "getopt.h"
29
#include "double-int.h"
30
#include "version.h"            /* for version_string & pkgversion_string.  */
31
#include "hashtab.h"
32
#include "xregex.h"
33
#include "obstack.h"
34
#include "gengtype.h"
35
#include "filenames.h"
36
 
37
/* Data types, macros, etc. used only in this file.  */
38
 
39
 
40
/* The list of output files.  */
41
outf_p output_files;
42
 
43
/* The output header file that is included into pretty much every
44
   source file.  */
45
outf_p header_file;
46
 
47
 
48
/* The name of the file containing the list of input files.  */
49
static char *inputlist;
50
 
51
/* The plugin input files and their number; in that case only
52
   a single file is produced.  */
53
static input_file **plugin_files;
54
static size_t nb_plugin_files;
55
 
56
/* The generated plugin output file and name.  */
57
static outf_p plugin_output;
58
static char *plugin_output_filename;
59
 
60
/* Our source directory and its length.  */
61
const char *srcdir;
62
size_t srcdir_len;
63
 
64
/* Variables used for reading and writing the state.  */
65
const char *read_state_filename;
66
const char *write_state_filename;
67
 
68
/* Variables to help debugging.  */
69
int do_dump;
70
int do_debug;
71
 
72
/* Level for verbose messages.  */
73
int verbosity_level;
74
 
75
/* We have a type count and use it to set the state_number of newly
76
   allocated types to some unique negative number.  */
77
static int type_count;
78
 
79
/* The backup directory should be in the same file system as the
80
   generated files, otherwise the rename(2) system call would fail.
81
   If NULL, no backup is made when overwriting a generated file.  */
82
static const char* backup_dir;  /* (-B) program option.  */
83
 
84
 
85
static outf_p create_file (const char *, const char *);
86
 
87
static const char *get_file_basename (const input_file *);
88
static const char *get_file_realbasename (const input_file *);
89
 
90
static int get_prefix_langdir_index (const char *);
91
static const char *get_file_langdir (const input_file *);
92
 
93
 
94
/* Nonzero iff an error has occurred.  */
95
bool hit_error = false;
96
 
97
static void gen_rtx_next (void);
98
static void write_rtx_next (void);
99
static void open_base_files (void);
100
static void close_output_files (void);
101
 
102
/* Report an error at POS, printing MSG.  */
103
 
104
void
105
error_at_line (const struct fileloc *pos, const char *msg, ...)
106
{
107
  va_list ap;
108
 
109
  gcc_assert (pos != NULL && pos->file != NULL);
110
  va_start (ap, msg);
111
 
112
  fprintf (stderr, "%s:%d: ", get_input_file_name (pos->file), pos->line);
113
  vfprintf (stderr, msg, ap);
114
  fputc ('\n', stderr);
115
  hit_error = true;
116
 
117
  va_end (ap);
118
}
119
 
120
/* asprintf, but produces fatal message on out-of-memory.  */
121
char *
122
xasprintf (const char *format, ...)
123
{
124
  int n;
125
  char *result;
126
  va_list ap;
127
 
128
  va_start (ap, format);
129
  n = vasprintf (&result, format, ap);
130
  if (result == NULL || n < 0)
131
    fatal ("out of memory");
132
  va_end (ap);
133
 
134
  return result;
135
}
136
 
137
/* Input file handling. */
138
 
139
/* Table of all input files.  */
140
const input_file **gt_files;
141
size_t num_gt_files;
142
 
143
/* A number of places use the name of this "gengtype.c" file for a
144
   location for things that we can't rely on the source to define.
145
   Make sure we can still use pointer comparison on filenames.  */
146
input_file* this_file;
147
/* The "system.h" file is likewise specially useful.  */
148
input_file* system_h_file;
149
 
150
/* Vector of per-language directories.  */
151
const char **lang_dir_names;
152
size_t num_lang_dirs;
153
 
154
/* An array of output files suitable for definitions.  There is one
155
   BASE_FILES entry for each language.  */
156
static outf_p *base_files;
157
 
158
 
159
 
160
#if ENABLE_CHECKING
161
/* Utility debugging function, printing the various type counts within
162
   a list of types.  Called thru the DBGPRINT_COUNT_TYPE macro.  */
163
void
164
dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
165
{
166
  int nb_types = 0, nb_scalar = 0, nb_string = 0;
167
  int nb_struct = 0, nb_union = 0, nb_array = 0, nb_pointer = 0;
168
  int nb_lang_struct = 0, nb_param_struct = 0;
169
  type_p p = NULL;
170
  for (p = t; p; p = p->next)
171
    {
172
      nb_types++;
173
      switch (p->kind)
174
        {
175
        case TYPE_SCALAR:
176
          nb_scalar++;
177
          break;
178
        case TYPE_STRING:
179
          nb_string++;
180
          break;
181
        case TYPE_STRUCT:
182
          nb_struct++;
183
          break;
184
        case TYPE_UNION:
185
          nb_union++;
186
          break;
187
        case TYPE_POINTER:
188
          nb_pointer++;
189
          break;
190
        case TYPE_ARRAY:
191
          nb_array++;
192
          break;
193
        case TYPE_LANG_STRUCT:
194
          nb_lang_struct++;
195
          break;
196
        case TYPE_PARAM_STRUCT:
197
          nb_param_struct++;
198
          break;
199
        default:
200
          gcc_unreachable ();
201
        }
202
    }
203
  fprintf (stderr, "\n" "%s:%d: %s: @@%%@@ %d types ::\n",
204
           lbasename (fil), lin, msg, nb_types);
205
  if (nb_scalar > 0 || nb_string > 0)
206
    fprintf (stderr, "@@%%@@ %d scalars, %d strings\n", nb_scalar, nb_string);
207
  if (nb_struct > 0 || nb_union > 0)
208
    fprintf (stderr, "@@%%@@ %d structs, %d unions\n", nb_struct, nb_union);
209
  if (nb_pointer > 0 || nb_array > 0)
210
    fprintf (stderr, "@@%%@@ %d pointers, %d arrays\n", nb_pointer, nb_array);
211
  if (nb_lang_struct > 0 || nb_param_struct > 0)
212
    fprintf (stderr, "@@%%@@ %d lang_structs, %d param_structs\n",
213
             nb_lang_struct, nb_param_struct);
214
  fprintf (stderr, "\n");
215
}
216
#endif /* ENABLE_CHECKING */
217
 
218
/* Scan the input file, LIST, and determine how much space we need to
219
   store strings in.  Also, count the number of language directories
220
   and files.  The numbers returned are overestimates as they does not
221
   consider repeated files.  */
222
static size_t
223
measure_input_list (FILE *list)
224
{
225
  size_t n = 0;
226
  int c;
227
  bool atbol = true;
228
  num_lang_dirs = 0;
229
  num_gt_files = plugin_files ? nb_plugin_files : 0;
230
  while ((c = getc (list)) != EOF)
231
    {
232
      n++;
233
      if (atbol)
234
        {
235
          if (c == '[')
236
            num_lang_dirs++;
237
          else
238
            {
239
              /* Add space for a lang_bitmap before the input file name.  */
240
              n += sizeof (lang_bitmap);
241
              num_gt_files++;
242
            }
243
          atbol = false;
244
        }
245
 
246
      if (c == '\n')
247
        atbol = true;
248
    }
249
 
250
  rewind (list);
251
  return n;
252
}
253
 
254
/* Read one input line from LIST to HEREP (which is updated).  A
255
   pointer to the string is returned via LINEP.  If it was a language
256
   subdirectory in square brackets, strip off the square brackets and
257
   return true.  Otherwise, leave space before the string for a
258
   lang_bitmap, and return false.  At EOF, returns false, does not
259
   touch *HEREP, and sets *LINEP to NULL.  POS is used for
260
   diagnostics.  */
261
static bool
262
read_input_line (FILE *list, char **herep, char **linep, struct fileloc *pos)
263
{
264
  char *here = *herep;
265
  char *line;
266
  int c = getc (list);
267
 
268
  /* Read over whitespace.  */
269
  while (c == '\n' || c == ' ')
270
    c = getc (list);
271
 
272
  if (c == EOF)
273
    {
274
      *linep = 0;
275
      return false;
276
    }
277
  else if (c == '[')
278
    {
279
      /* No space for a lang_bitmap is necessary.  Discard the '['. */
280
      c = getc (list);
281
      line = here;
282
      while (c != ']' && c != '\n' && c != EOF)
283
        {
284
          *here++ = c;
285
          c = getc (list);
286
        }
287
      *here++ = '\0';
288
 
289
      if (c == ']')
290
        {
291
          c = getc (list);      /* eat what should be a newline */
292
          if (c != '\n' && c != EOF)
293
            error_at_line (pos, "junk on line after language tag [%s]", line);
294
        }
295
      else
296
        error_at_line (pos, "missing close bracket for language tag [%s",
297
                       line);
298
 
299
      *herep = here;
300
      *linep = line;
301
      return true;
302
    }
303
  else
304
    {
305
      /* Leave space for a lang_bitmap.  */
306
      memset (here, 0, sizeof (lang_bitmap));
307
      here += sizeof (lang_bitmap);
308
      line = here;
309
      do
310
        {
311
          *here++ = c;
312
          c = getc (list);
313
        }
314
      while (c != EOF && c != '\n');
315
      *here++ = '\0';
316
      *herep = here;
317
      *linep = line;
318
      return false;
319
    }
320
}
321
 
322
/* Read the list of input files from LIST and compute all of the
323
   relevant tables.  There is one file per line of the list.  At
324
   first, all the files on the list are language-generic, but
325
   eventually a line will appear which is the name of a language
326
   subdirectory in square brackets, like this: [cp].  All subsequent
327
   files are specific to that language, until another language
328
   subdirectory tag appears.  Files can appear more than once, if
329
   they apply to more than one language.  */
330
static void
331
read_input_list (const char *listname)
332
{
333
  FILE *list = fopen (listname, "r");
334
  if (!list)
335
    fatal ("cannot open %s: %s", listname, xstrerror (errno));
336
  else
337
    {
338
      struct fileloc epos;
339
      size_t bufsz = measure_input_list (list);
340
      char *buf = XNEWVEC (char, bufsz);
341
      char *here = buf;
342
      char *committed = buf;
343
      char *limit = buf + bufsz;
344
      char *line;
345
      bool is_language;
346
      size_t langno = 0;
347
      size_t nfiles = 0;
348
      lang_bitmap curlangs = (1 << num_lang_dirs) - 1;
349
 
350
      epos.file = input_file_by_name (listname);
351
      epos.line = 0;
352
 
353
      lang_dir_names = XNEWVEC (const char *, num_lang_dirs);
354
      gt_files = XNEWVEC (const input_file *, num_gt_files);
355
 
356
      for (;;)
357
        {
358
        next_line:
359
          epos.line++;
360
          committed = here;
361
          is_language = read_input_line (list, &here, &line, &epos);
362
          gcc_assert (here <= limit);
363
          if (line == 0)
364
            break;
365
          else if (is_language)
366
            {
367
              size_t i;
368
              gcc_assert (langno <= num_lang_dirs);
369
              for (i = 0; i < langno; i++)
370
                if (strcmp (lang_dir_names[i], line) == 0)
371
                  {
372
                    error_at_line (&epos, "duplicate language tag [%s]",
373
                                   line);
374
                    curlangs = 1 << i;
375
                    here = committed;
376
                    goto next_line;
377
                  }
378
 
379
              curlangs = 1 << langno;
380
              lang_dir_names[langno++] = line;
381
            }
382
          else
383
            {
384
              size_t i;
385
              input_file *inpf = input_file_by_name (line);
386
              gcc_assert (nfiles <= num_gt_files);
387
              for (i = 0; i < nfiles; i++)
388
                /* Since the input_file-s are uniquely hash-consed, we
389
                   can just compare pointers! */
390
                if (gt_files[i] == inpf)
391
                  {
392
                    /* Throw away the string we just read, and add the
393
                       current language to the existing string's bitmap.  */
394
                    lang_bitmap bmap = get_lang_bitmap (inpf);
395
                    if (bmap & curlangs)
396
                      error_at_line (&epos,
397
                                     "file %s specified more than once "
398
                                     "for language %s", line,
399
                                     langno ==
400
 
401
                                                                  1]);
402
 
403
                    bmap |= curlangs;
404
                    set_lang_bitmap (inpf, bmap);
405
                    here = committed;
406
                    goto next_line;
407
                  }
408
 
409
              set_lang_bitmap (inpf, curlangs);
410
              gt_files[nfiles++] = inpf;
411
            }
412
        }
413
      /* Update the global counts now that we know accurately how many
414
         things there are.  (We do not bother resizing the arrays down.)  */
415
      num_lang_dirs = langno;
416
      /* Add the plugin files if provided.  */
417
      if (plugin_files)
418
        {
419
          size_t i;
420
          for (i = 0; i < nb_plugin_files; i++)
421
            gt_files[nfiles++] = plugin_files[i];
422
        }
423
      num_gt_files = nfiles;
424
    }
425
 
426
  /* Sanity check: any file that resides in a language subdirectory
427
     (e.g. 'cp') ought to belong to the corresponding language.
428
     ??? Still true if for instance ObjC++ is enabled and C++ isn't?
429
     (Can you even do that?  Should you be allowed to?)  */
430
  {
431
    size_t f;
432
    for (f = 0; f < num_gt_files; f++)
433
      {
434
        lang_bitmap bitmap = get_lang_bitmap (gt_files[f]);
435
        const char *basename = get_file_basename (gt_files[f]);
436
        const char *slashpos = strchr (basename, '/');
437
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
438
        const char *slashpos2 = strchr (basename, '\\');
439
 
440
        if (!slashpos || (slashpos2 && slashpos2 < slashpos))
441
          slashpos = slashpos2;
442
#endif
443
 
444
        if (slashpos)
445
          {
446
            size_t l;
447
            for (l = 0; l < num_lang_dirs; l++)
448
              if ((size_t) (slashpos - basename) == strlen (lang_dir_names[l])
449
                  && memcmp (basename, lang_dir_names[l],
450
                             strlen (lang_dir_names[l])) == 0)
451
                {
452
                  if (!(bitmap & (1 << l)))
453
                    error ("%s is in language directory '%s' but is not "
454
                           "tagged for that language",
455
                           basename, lang_dir_names[l]);
456
                  break;
457
                }
458
          }
459
      }
460
  }
461
 
462
  if (ferror (list))
463
    fatal ("error reading %s: %s", listname, xstrerror (errno));
464
 
465
  fclose (list);
466
}
467
 
468
 
469
 
470
/* The one and only TYPE_STRING.  */
471
 
472
struct type string_type = {
473
  TYPE_STRING, 0, 0, 0, GC_USED, {0}
474
};
475
 
476
/* The two and only TYPE_SCALARs.  Their u.scalar_is_char flags are
477
   set early in main.  */
478
 
479
struct type scalar_nonchar = {
480
  TYPE_SCALAR, 0, 0, 0, GC_USED, {0}
481
};
482
 
483
struct type scalar_char = {
484
  TYPE_SCALAR, 0, 0, 0, GC_USED, {0}
485
};
486
 
487
/* Lists of various things.  */
488
 
489
pair_p typedefs;
490
type_p structures;
491
type_p param_structs;
492
pair_p variables;
493
 
494
static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]);
495
static type_p adjust_field_tree_exp (type_p t, options_p opt);
496
static type_p adjust_field_rtx_def (type_p t, options_p opt);
497
 
498
/* Define S as a typedef to T at POS.  */
499
 
500
void
501
do_typedef (const char *s, type_p t, struct fileloc *pos)
502
{
503
  pair_p p;
504
 
505
  /* temporary kludge - gengtype doesn't handle conditionals or
506
     macros.  Ignore any attempt to typedef CUMULATIVE_ARGS, unless it
507
     is coming from this file (main() sets them up with safe dummy
508
     definitions).  */
509
  if (!strcmp (s, "CUMULATIVE_ARGS") && pos->file != this_file)
510
    return;
511
 
512
  for (p = typedefs; p != NULL; p = p->next)
513
    if (strcmp (p->name, s) == 0)
514
      {
515
        if (p->type != t)
516
          {
517
            error_at_line (pos, "type `%s' previously defined", s);
518
            error_at_line (&p->line, "previously defined here");
519
          }
520
        return;
521
      }
522
 
523
  p = XNEW (struct pair);
524
  p->next = typedefs;
525
  p->name = s;
526
  p->type = t;
527
  p->line = *pos;
528
  p->opt = NULL;
529
  typedefs = p;
530
}
531
 
532
/* Define S as a typename of a scalar.  Cannot be used to define
533
   typedefs of 'char'.  Note: is also used for pointer-to-function
534
   typedefs (which are therefore not treated as pointers).  */
535
 
536
void
537
do_scalar_typedef (const char *s, struct fileloc *pos)
538
{
539
  do_typedef (s, &scalar_nonchar, pos);
540
}
541
 
542
/* Return the type previously defined for S.  Use POS to report errors.  */
543
 
544
type_p
545
resolve_typedef (const char *s, struct fileloc *pos)
546
{
547
  pair_p p;
548
  for (p = typedefs; p != NULL; p = p->next)
549
    if (strcmp (p->name, s) == 0)
550
      return p->type;
551
  error_at_line (pos, "unidentified type `%s'", s);
552
  return &scalar_nonchar;       /* treat as "int" */
553
}
554
 
555
/* Create and return a new structure with tag NAME (or a union iff
556
   ISUNION is nonzero), at POS with fields FIELDS and options O.  */
557
 
558
type_p
559
new_structure (const char *name, int isunion, struct fileloc *pos,
560
               pair_p fields, options_p o)
561
{
562
  type_p si;
563
  type_p s = NULL;
564
  lang_bitmap bitmap = get_lang_bitmap (pos->file);
565
 
566
  for (si = structures; si != NULL; si = si->next)
567
    if (strcmp (name, si->u.s.tag) == 0 && UNION_P (si) == isunion)
568
      {
569
        type_p ls = NULL;
570
        if (si->kind == TYPE_LANG_STRUCT)
571
          {
572
            ls = si;
573
 
574
            for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
575
              if (si->u.s.bitmap == bitmap)
576
                s = si;
577
          }
578
        else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
579
          {
580
            ls = si;
581
            type_count++;
582
            si = XCNEW (struct type);
583
            memcpy (si, ls, sizeof (struct type));
584
            ls->kind = TYPE_LANG_STRUCT;
585
            ls->u.s.lang_struct = si;
586
            ls->u.s.fields = NULL;
587
            si->next = NULL;
588
            si->state_number = -type_count;
589
            si->pointer_to = NULL;
590
            si->u.s.lang_struct = ls;
591
          }
592
        else
593
          s = si;
594
 
595
        if (ls != NULL && s == NULL)
596
          {
597
            type_count++;
598
            s = XCNEW (struct type);
599
            s->state_number = -type_count;
600
            s->next = ls->u.s.lang_struct;
601
            ls->u.s.lang_struct = s;
602
            s->u.s.lang_struct = ls;
603
          }
604
        break;
605
      }
606
 
607
  if (s == NULL)
608
    {
609
      type_count++;
610
      s = XCNEW (struct type);
611
      s->state_number = -type_count;
612
      s->next = structures;
613
      structures = s;
614
    }
615
 
616
  if (s->u.s.line.file != NULL
617
      || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
618
    {
619
      error_at_line (pos, "duplicate definition of '%s %s'",
620
                     isunion ? "union" : "struct", s->u.s.tag);
621
      error_at_line (&s->u.s.line, "previous definition here");
622
    }
623
 
624
  s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
625
  s->u.s.tag = name;
626
  s->u.s.line = *pos;
627
  s->u.s.fields = fields;
628
  s->u.s.opt = o;
629
  s->u.s.bitmap = bitmap;
630
  if (s->u.s.lang_struct)
631
    s->u.s.lang_struct->u.s.bitmap |= bitmap;
632
 
633
  return s;
634
}
635
 
636
/* Return the previously-defined structure with tag NAME (or a union
637
   iff ISUNION is nonzero), or a new empty structure or union if none
638
   was defined previously.  */
639
 
640
type_p
641
find_structure (const char *name, int isunion)
642
{
643
  type_p s;
644
 
645
  for (s = structures; s != NULL; s = s->next)
646
    if (strcmp (name, s->u.s.tag) == 0 && UNION_P (s) == isunion)
647
      return s;
648
 
649
  type_count++;
650
  s = XCNEW (struct type);
651
  s->next = structures;
652
  s->state_number = -type_count;
653
  structures = s;
654
  s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
655
  s->u.s.tag = name;
656
  structures = s;
657
  return s;
658
}
659
 
660
/* Return the previously-defined parameterized structure for structure
661
   T and parameters PARAM, or a new parameterized empty structure or
662
   union if none was defined previously.  */
663
 
664
static type_p
665
find_param_structure (type_p t, type_p param[NUM_PARAM])
666
{
667
  type_p res;
668
 
669
  for (res = param_structs; res; res = res->next)
670
    if (res->u.param_struct.stru == t
671
        && memcmp (res->u.param_struct.param, param,
672
                   sizeof (type_p) * NUM_PARAM) == 0)
673
      break;
674
  if (res == NULL)
675
    {
676
      type_count++;
677
      res = XCNEW (struct type);
678
      res->kind = TYPE_PARAM_STRUCT;
679
      res->next = param_structs;
680
      res->state_number = -type_count;
681
      param_structs = res;
682
      res->u.param_struct.stru = t;
683
      memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
684
    }
685
  return res;
686
}
687
 
688
/* Return a scalar type with name NAME.  */
689
 
690
type_p
691
create_scalar_type (const char *name)
692
{
693
  if (!strcmp (name, "char") || !strcmp (name, "unsigned char"))
694
    return &scalar_char;
695
  else
696
    return &scalar_nonchar;
697
}
698
 
699
/* Return a pointer to T.  */
700
 
701
type_p
702
create_pointer (type_p t)
703
{
704
  if (!t->pointer_to)
705
    {
706
      type_p r = XCNEW (struct type);
707
      type_count++;
708
      r->state_number = -type_count;
709
      r->kind = TYPE_POINTER;
710
      r->u.p = t;
711
      t->pointer_to = r;
712
    }
713
  return t->pointer_to;
714
}
715
 
716
/* Return an array of length LEN.  */
717
 
718
type_p
719
create_array (type_p t, const char *len)
720
{
721
  type_p v;
722
 
723
  type_count++;
724
  v = XCNEW (struct type);
725
  v->kind = TYPE_ARRAY;
726
  v->state_number = -type_count;
727
  v->u.a.p = t;
728
  v->u.a.len = len;
729
  return v;
730
}
731
 
732
/* Return a string options structure with name NAME and info INFO.
733
   NEXT is the next option in the chain.  */
734
options_p
735
create_string_option (options_p next, const char *name, const char *info)
736
{
737
  options_p o = XNEW (struct options);
738
  o->kind = OPTION_STRING;
739
  o->next = next;
740
  o->name = name;
741
  o->info.string = info;
742
  return o;
743
}
744
 
745
/* Create a type options structure with name NAME and info INFO.  NEXT
746
   is the next option in the chain.  */
747
options_p
748
create_type_option (options_p next, const char* name, type_p info)
749
{
750
  options_p o = XNEW (struct options);
751
  o->next = next;
752
  o->name = name;
753
  o->kind = OPTION_TYPE;
754
  o->info.type = info;
755
  return o;
756
}
757
 
758
/* Create a nested pointer options structure with name NAME and info
759
   INFO.  NEXT is the next option in the chain.  */
760
options_p
761
create_nested_option (options_p next, const char* name,
762
                      struct nested_ptr_data* info)
763
{
764
  options_p o;
765
  o = XNEW (struct options);
766
  o->next = next;
767
  o->name = name;
768
  o->kind = OPTION_NESTED;
769
  o->info.nested = info;
770
  return o;
771
}
772
 
773
/* Return an options structure for a "nested_ptr" option.  */
774
options_p
775
create_nested_ptr_option (options_p next, type_p t,
776
                          const char *to, const char *from)
777
{
778
  struct nested_ptr_data *d = XNEW (struct nested_ptr_data);
779
 
780
  d->type = adjust_field_type (t, 0);
781
  d->convert_to = to;
782
  d->convert_from = from;
783
  return create_nested_option (next, "nested_ptr", d);
784
}
785
 
786
/* Add a variable named S of type T with options O defined at POS,
787
   to `variables'.  */
788
void
789
note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
790
{
791
  pair_p n;
792
  n = XNEW (struct pair);
793
  n->name = s;
794
  n->type = t;
795
  n->line = *pos;
796
  n->opt = o;
797
  n->next = variables;
798
  variables = n;
799
}
800
 
801
/* Most-general structure field creator.  */
802
static pair_p
803
create_field_all (pair_p next, type_p type, const char *name, options_p opt,
804
                  const input_file *inpf, int line)
805
{
806
  pair_p field;
807
 
808
  field = XNEW (struct pair);
809
  field->next = next;
810
  field->type = type;
811
  field->name = name;
812
  field->opt = opt;
813
  field->line.file = inpf;
814
  field->line.line = line;
815
  return field;
816
}
817
 
818
/* Create a field that came from the source code we are scanning,
819
   i.e. we have a 'struct fileloc', and possibly options; also,
820
   adjust_field_type should be called.  */
821
pair_p
822
create_field_at (pair_p next, type_p type, const char *name, options_p opt,
823
                 struct fileloc *pos)
824
{
825
  return create_field_all (next, adjust_field_type (type, opt),
826
                           name, opt, pos->file, pos->line);
827
}
828
 
829
/* Create a fake field with the given type and name.  NEXT is the next
830
   field in the chain.  */
831
#define create_field(next,type,name) \
832
    create_field_all(next,type,name, 0, this_file, __LINE__)
833
 
834
/* Like create_field, but the field is only valid when condition COND
835
   is true.  */
836
 
837
static pair_p
838
create_optional_field_ (pair_p next, type_p type, const char *name,
839
                        const char *cond, int line)
840
{
841
  static int id = 1;
842
  pair_p union_fields;
843
  type_p union_type;
844
 
845
  /* Create a fake union type with a single nameless field of type TYPE.
846
     The field has a tag of "1".  This allows us to make the presence
847
     of a field of type TYPE depend on some boolean "desc" being true.  */
848
  union_fields = create_field (NULL, type, "");
849
  union_fields->opt =
850
    create_string_option (union_fields->opt, "dot", "");
851
  union_fields->opt =
852
    create_string_option (union_fields->opt, "tag", "1");
853
  union_type =
854
    new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
855
                   &lexer_line, union_fields, NULL);
856
 
857
  /* Create the field and give it the new fake union type.  Add a "desc"
858
     tag that specifies the condition under which the field is valid.  */
859
  return create_field_all (next, union_type, name,
860
                           create_string_option (0, "desc", cond),
861
                           this_file, line);
862
}
863
 
864
#define create_optional_field(next,type,name,cond)      \
865
       create_optional_field_(next,type,name,cond,__LINE__)
866
 
867
/* Reverse a linked list of 'struct pair's in place.  */
868
pair_p
869
nreverse_pairs (pair_p list)
870
{
871
  pair_p prev = 0, p, next;
872
  for (p = list; p; p = next)
873
    {
874
      next = p->next;
875
      p->next = prev;
876
      prev = p;
877
    }
878
  return prev;
879
}
880
 
881
 
882
/* We don't care how long a CONST_DOUBLE is.  */
883
#define CONST_DOUBLE_FORMAT "ww"
884
/* We don't want to see codes that are only for generator files.  */
885
#undef GENERATOR_FILE
886
 
887
enum rtx_code
888
{
889
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
890
#include "rtl.def"
891
#undef DEF_RTL_EXPR
892
  NUM_RTX_CODE
893
};
894
 
895
static const char *const rtx_name[NUM_RTX_CODE] = {
896
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
897
#include "rtl.def"
898
#undef DEF_RTL_EXPR
899
};
900
 
901
static const char *const rtx_format[NUM_RTX_CODE] = {
902
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
903
#include "rtl.def"
904
#undef DEF_RTL_EXPR
905
};
906
 
907
static int rtx_next_new[NUM_RTX_CODE];
908
 
909
/* We also need codes and names for insn notes (not register notes).
910
   Note that we do *not* bias the note values here.  */
911
enum insn_note
912
{
913
#define DEF_INSN_NOTE(NAME) NAME,
914
#include "insn-notes.def"
915
#undef DEF_INSN_NOTE
916
 
917
  NOTE_INSN_MAX
918
};
919
 
920
/* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
921
   default field for line number notes.  */
922
static const char *const note_insn_name[NOTE_INSN_MAX + 1] = {
923
#define DEF_INSN_NOTE(NAME) #NAME,
924
#include "insn-notes.def"
925
#undef DEF_INSN_NOTE
926
};
927
 
928
#undef CONST_DOUBLE_FORMAT
929
#define GENERATOR_FILE
930
 
931
/* Generate the contents of the rtx_next array.  This really doesn't belong
932
   in gengtype at all, but it's needed for adjust_field_rtx_def.  */
933
 
934
static void
935
gen_rtx_next (void)
936
{
937
  int i;
938
  for (i = 0; i < NUM_RTX_CODE; i++)
939
    {
940
      int k;
941
 
942
      rtx_next_new[i] = -1;
943
      if (strncmp (rtx_format[i], "iuu", 3) == 0)
944
        rtx_next_new[i] = 2;
945
      else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
946
        rtx_next_new[i] = 1;
947
      else
948
        for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
949
          if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
950
            rtx_next_new[i] = k;
951
    }
952
}
953
 
954
/* Write out the contents of the rtx_next array.  */
955
static void
956
write_rtx_next (void)
957
{
958
  outf_p f = get_output_file_with_visibility (NULL);
959
  int i;
960
  if (!f)
961
    return;
962
 
963
  oprintf (f, "\n/* Used to implement the RTX_NEXT macro.  */\n");
964
  oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
965
  for (i = 0; i < NUM_RTX_CODE; i++)
966
    if (rtx_next_new[i] == -1)
967
      oprintf (f, "  0,\n");
968
    else
969
      oprintf (f,
970
               "  RTX_HDR_SIZE + %d * sizeof (rtunion),\n", rtx_next_new[i]);
971
  oprintf (f, "};\n");
972
}
973
 
974
/* Handle `special("rtx_def")'.  This is a special case for field
975
   `fld' of struct rtx_def, which is an array of unions whose values
976
   are based in a complex way on the type of RTL.  */
977
 
978
static type_p
979
adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
980
{
981
  pair_p flds = NULL;
982
  options_p nodot;
983
  int i;
984
  type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
985
  type_p basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
986
 
987
  if (t->kind != TYPE_UNION)
988
    {
989
      error_at_line (&lexer_line,
990
                     "special `rtx_def' must be applied to a union");
991
      return &string_type;
992
    }
993
 
994
  nodot = create_string_option (NULL, "dot", "");
995
 
996
  rtx_tp = create_pointer (find_structure ("rtx_def", 0));
997
  rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
998
  tree_tp = create_pointer (find_structure ("tree_node", 1));
999
  mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
1000
  reg_attrs_tp =
1001
    create_pointer (find_structure ("reg_attrs", 0));
1002
  basic_block_tp =
1003
    create_pointer (find_structure ("basic_block_def", 0));
1004
  constant_tp =
1005
    create_pointer (find_structure ("constant_descriptor_rtx", 0));
1006
  scalar_tp = &scalar_nonchar;  /* rtunion int */
1007
 
1008
  {
1009
    pair_p note_flds = NULL;
1010
    int c;
1011
 
1012
    for (c = 0; c <= NOTE_INSN_MAX; c++)
1013
      {
1014
        switch (c)
1015
          {
1016
          case NOTE_INSN_MAX:
1017
          case NOTE_INSN_DELETED_LABEL:
1018
          case NOTE_INSN_DELETED_DEBUG_LABEL:
1019
            note_flds = create_field (note_flds, &string_type, "rt_str");
1020
            break;
1021
 
1022
          case NOTE_INSN_BLOCK_BEG:
1023
          case NOTE_INSN_BLOCK_END:
1024
            note_flds = create_field (note_flds, tree_tp, "rt_tree");
1025
            break;
1026
 
1027
          case NOTE_INSN_VAR_LOCATION:
1028
          case NOTE_INSN_CALL_ARG_LOCATION:
1029
            note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
1030
            break;
1031
 
1032
          default:
1033
            note_flds = create_field (note_flds, scalar_tp, "rt_int");
1034
            break;
1035
          }
1036
        /* NOTE_INSN_MAX is used as the default field for line
1037
           number notes.  */
1038
        if (c == NOTE_INSN_MAX)
1039
          note_flds->opt =
1040
            create_string_option (nodot, "default", "");
1041
        else
1042
          note_flds->opt =
1043
            create_string_option (nodot, "tag", note_insn_name[c]);
1044
      }
1045
    note_union_tp = new_structure ("rtx_def_note_subunion", 1,
1046
                                   &lexer_line, note_flds, NULL);
1047
  }
1048
  /* Create a type to represent the various forms of SYMBOL_REF_DATA.  */
1049
  {
1050
    pair_p sym_flds;
1051
    sym_flds = create_field (NULL, tree_tp, "rt_tree");
1052
    sym_flds->opt = create_string_option (nodot, "default", "");
1053
    sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
1054
    sym_flds->opt = create_string_option (nodot, "tag", "1");
1055
    symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
1056
                                     &lexer_line, sym_flds, NULL);
1057
  }
1058
  for (i = 0; i < NUM_RTX_CODE; i++)
1059
    {
1060
      pair_p subfields = NULL;
1061
      size_t aindex, nmindex;
1062
      const char *sname;
1063
      type_p substruct;
1064
      char *ftag;
1065
 
1066
      for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
1067
        {
1068
          type_p t;
1069
          const char *subname;
1070
 
1071
          switch (rtx_format[i][aindex])
1072
            {
1073
            case '*':
1074
            case 'i':
1075
            case 'n':
1076
            case 'w':
1077
              t = scalar_tp;
1078
              subname = "rt_int";
1079
              break;
1080
 
1081
            case '0':
1082
              if (i == MEM && aindex == 1)
1083
                t = mem_attrs_tp, subname = "rt_mem";
1084
              else if (i == JUMP_INSN && aindex == 8)
1085
                t = rtx_tp, subname = "rt_rtx";
1086
              else if (i == CODE_LABEL && aindex == 5)
1087
                t = scalar_tp, subname = "rt_int";
1088
              else if (i == CODE_LABEL && aindex == 4)
1089
                t = rtx_tp, subname = "rt_rtx";
1090
              else if (i == LABEL_REF && (aindex == 1 || aindex == 2))
1091
                t = rtx_tp, subname = "rt_rtx";
1092
              else if (i == NOTE && aindex == 4)
1093
                t = note_union_tp, subname = "";
1094
              else if (i == NOTE && aindex == 5)
1095
                t = scalar_tp, subname = "rt_int";
1096
              else if (i == NOTE && aindex >= 7)
1097
                t = scalar_tp, subname = "rt_int";
1098
              else if (i == ADDR_DIFF_VEC && aindex == 4)
1099
                t = scalar_tp, subname = "rt_int";
1100
              else if (i == VALUE && aindex == 0)
1101
                t = scalar_tp, subname = "rt_int";
1102
              else if (i == DEBUG_EXPR && aindex == 0)
1103
                t = tree_tp, subname = "rt_tree";
1104
              else if (i == REG && aindex == 1)
1105
                t = scalar_tp, subname = "rt_int";
1106
              else if (i == REG && aindex == 2)
1107
                t = reg_attrs_tp, subname = "rt_reg";
1108
              else if (i == SCRATCH && aindex == 0)
1109
                t = scalar_tp, subname = "rt_int";
1110
              else if (i == SYMBOL_REF && aindex == 1)
1111
                t = scalar_tp, subname = "rt_int";
1112
              else if (i == SYMBOL_REF && aindex == 2)
1113
                t = symbol_union_tp, subname = "";
1114
              else if (i == BARRIER && aindex >= 3)
1115
                t = scalar_tp, subname = "rt_int";
1116
              else if (i == ENTRY_VALUE && aindex == 0)
1117
                t = rtx_tp, subname = "rt_rtx";
1118
              else
1119
                {
1120
                  error_at_line
1121
                    (&lexer_line,
1122
                     "rtx type `%s' has `0' in position %lu, can't handle",
1123
                     rtx_name[i], (unsigned long) aindex);
1124
                  t = &string_type;
1125
                  subname = "rt_int";
1126
                }
1127
              break;
1128
 
1129
            case 's':
1130
            case 'S':
1131
            case 'T':
1132
              t = &string_type;
1133
              subname = "rt_str";
1134
              break;
1135
 
1136
            case 'e':
1137
            case 'u':
1138
              t = rtx_tp;
1139
              subname = "rt_rtx";
1140
              break;
1141
 
1142
            case 'E':
1143
            case 'V':
1144
              t = rtvec_tp;
1145
              subname = "rt_rtvec";
1146
              break;
1147
 
1148
            case 't':
1149
              t = tree_tp;
1150
              subname = "rt_tree";
1151
              break;
1152
 
1153
            case 'B':
1154
              t = basic_block_tp;
1155
              subname = "rt_bb";
1156
              break;
1157
 
1158
            default:
1159
              error_at_line
1160
                (&lexer_line,
1161
                 "rtx type `%s' has `%c' in position %lu, can't handle",
1162
                 rtx_name[i], rtx_format[i][aindex],
1163
                 (unsigned long) aindex);
1164
              t = &string_type;
1165
              subname = "rt_int";
1166
              break;
1167
            }
1168
 
1169
          subfields = create_field (subfields, t,
1170
                                    xasprintf (".fld[%lu].%s",
1171
                                               (unsigned long) aindex,
1172
                                               subname));
1173
          subfields->opt = nodot;
1174
          if (t == note_union_tp)
1175
            subfields->opt =
1176
              create_string_option (subfields->opt, "desc",
1177
                                    "NOTE_KIND (&%0)");
1178
          if (t == symbol_union_tp)
1179
            subfields->opt =
1180
              create_string_option (subfields->opt, "desc",
1181
                                    "CONSTANT_POOL_ADDRESS_P (&%0)");
1182
        }
1183
 
1184
      if (i == SYMBOL_REF)
1185
        {
1186
          /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P
1187
             holds.  */
1188
          type_p field_tp = find_structure ("block_symbol", 0);
1189
          subfields
1190
            = create_optional_field (subfields, field_tp, "block_sym",
1191
                                     "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
1192
        }
1193
 
1194
      sname = xasprintf ("rtx_def_%s", rtx_name[i]);
1195
      substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
1196
 
1197
      ftag = xstrdup (rtx_name[i]);
1198
      for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
1199
        ftag[nmindex] = TOUPPER (ftag[nmindex]);
1200
      flds = create_field (flds, substruct, "");
1201
      flds->opt = create_string_option (nodot, "tag", ftag);
1202
    }
1203
  return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
1204
}
1205
 
1206
/* Handle `special("tree_exp")'.  This is a special case for
1207
   field `operands' of struct tree_exp, which although it claims to contain
1208
   pointers to trees, actually sometimes contains pointers to RTL too.
1209
   Passed T, the old type of the field, and OPT its options.  Returns
1210
   a new type for the field.  */
1211
 
1212
static type_p
1213
adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
1214
{
1215
  pair_p flds;
1216
  options_p nodot;
1217
 
1218
  if (t->kind != TYPE_ARRAY)
1219
    {
1220
      error_at_line (&lexer_line,
1221
                     "special `tree_exp' must be applied to an array");
1222
      return &string_type;
1223
    }
1224
 
1225
  nodot = create_string_option (NULL, "dot", "");
1226
 
1227
  flds = create_field (NULL, t, "");
1228
  flds->opt = create_string_option (nodot, "length",
1229
                                    "TREE_OPERAND_LENGTH ((tree) &%0)");
1230
  flds->opt = create_string_option (flds->opt, "default", "");
1231
 
1232
  return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
1233
}
1234
 
1235
/* Perform any special processing on a type T, about to become the type
1236
   of a field.  Return the appropriate type for the field.
1237
   At present:
1238
   - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
1239
   - Similarly for arrays of pointer-to-char;
1240
   - Converts structures for which a parameter is provided to
1241
     TYPE_PARAM_STRUCT;
1242
   - Handles "special" options.
1243
*/
1244
 
1245
type_p
1246
adjust_field_type (type_p t, options_p opt)
1247
{
1248
  int length_p = 0;
1249
  const int pointer_p = t->kind == TYPE_POINTER;
1250
  type_p params[NUM_PARAM];
1251
  int params_p = 0;
1252
  int i;
1253
 
1254
  for (i = 0; i < NUM_PARAM; i++)
1255
    params[i] = NULL;
1256
 
1257
  for (; opt; opt = opt->next)
1258
    if (strcmp (opt->name, "length") == 0)
1259
      length_p = 1;
1260
    else if ((strcmp (opt->name, "param_is") == 0
1261
              || (strncmp (opt->name, "param", 5) == 0
1262
                  && ISDIGIT (opt->name[5])
1263
                  && strcmp (opt->name + 6, "_is") == 0))
1264
             && opt->kind == OPTION_TYPE)
1265
      {
1266
        int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
1267
 
1268
        if (!UNION_OR_STRUCT_P (t)
1269
            && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p)))
1270
          {
1271
            error_at_line (&lexer_line,
1272
                           "option `%s' may only be applied to structures or structure pointers",
1273
                           opt->name);
1274
            return t;
1275
          }
1276
 
1277
        params_p = 1;
1278
        if (params[num] != NULL)
1279
          error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
1280
        if (!ISDIGIT (opt->name[5]))
1281
          params[num] = create_pointer (opt->info.type);
1282
        else
1283
          params[num] = opt->info.type;
1284
      }
1285
    else if (strcmp (opt->name, "special") == 0
1286
             && opt->kind == OPTION_STRING)
1287
      {
1288
        const char *special_name = opt->info.string;
1289
        if (strcmp (special_name, "tree_exp") == 0)
1290
          t = adjust_field_tree_exp (t, opt);
1291
        else if (strcmp (special_name, "rtx_def") == 0)
1292
          t = adjust_field_rtx_def (t, opt);
1293
        else
1294
          error_at_line (&lexer_line, "unknown special `%s'", special_name);
1295
      }
1296
 
1297
  if (params_p)
1298
    {
1299
      type_p realt;
1300
 
1301
      if (pointer_p)
1302
        t = t->u.p;
1303
      realt = find_param_structure (t, params);
1304
      t = pointer_p ? create_pointer (realt) : realt;
1305
    }
1306
 
1307
  if (!length_p
1308
      && pointer_p && t->u.p->kind == TYPE_SCALAR && t->u.p->u.scalar_is_char)
1309
    return &string_type;
1310
  if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
1311
      && t->u.a.p->u.p->kind == TYPE_SCALAR
1312
      && t->u.a.p->u.p->u.scalar_is_char)
1313
    return create_array (&string_type, t->u.a.len);
1314
 
1315
  return t;
1316
}
1317
 
1318
 
1319
static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
1320
static void set_gc_used (pair_p);
1321
 
1322
/* Handle OPT for set_gc_used_type.  */
1323
 
1324
static void
1325
process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
1326
                    int *pass_param, int *length, int *skip,
1327
                    type_p *nested_ptr)
1328
{
1329
  options_p o;
1330
  for (o = opt; o; o = o->next)
1331
    if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO
1332
        && o->kind == OPTION_TYPE)
1333
      set_gc_used_type (o->info.type,
1334
                        GC_POINTED_TO, NULL);
1335
    else if (strcmp (o->name, "maybe_undef") == 0)
1336
      *maybe_undef = 1;
1337
    else if (strcmp (o->name, "use_params") == 0)
1338
      *pass_param = 1;
1339
    else if (strcmp (o->name, "length") == 0)
1340
      *length = 1;
1341
    else if (strcmp (o->name, "skip") == 0)
1342
      *skip = 1;
1343
    else if (strcmp (o->name, "nested_ptr") == 0
1344
             && o->kind == OPTION_NESTED)
1345
      *nested_ptr = ((const struct nested_ptr_data *) o->info.nested)->type;
1346
}
1347
 
1348
 
1349
/* Set the gc_used field of T to LEVEL, and handle the types it references.  */
1350
static void
1351
set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
1352
{
1353
  if (t->gc_used >= level)
1354
    return;
1355
 
1356
  t->gc_used = level;
1357
 
1358
  switch (t->kind)
1359
    {
1360
    case TYPE_STRUCT:
1361
    case TYPE_UNION:
1362
      {
1363
        pair_p f;
1364
        int dummy;
1365
        type_p dummy2;
1366
 
1367
        process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
1368
                            &dummy2);
1369
 
1370
        for (f = t->u.s.fields; f; f = f->next)
1371
          {
1372
            int maybe_undef = 0;
1373
            int pass_param = 0;
1374
            int length = 0;
1375
            int skip = 0;
1376
            type_p nested_ptr = NULL;
1377
            process_gc_options (f->opt, level, &maybe_undef, &pass_param,
1378
                                &length, &skip, &nested_ptr);
1379
 
1380
            if (nested_ptr && f->type->kind == TYPE_POINTER)
1381
              set_gc_used_type (nested_ptr, GC_POINTED_TO,
1382
                                pass_param ? param : NULL);
1383
            else if (length && f->type->kind == TYPE_POINTER)
1384
              set_gc_used_type (f->type->u.p, GC_USED, NULL);
1385
            else if (maybe_undef && f->type->kind == TYPE_POINTER)
1386
              set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
1387
            else if (pass_param && f->type->kind == TYPE_POINTER && param)
1388
              set_gc_used_type (find_param_structure (f->type->u.p, param),
1389
                                GC_POINTED_TO, NULL);
1390
            else if (skip)
1391
              ;                 /* target type is not used through this field */
1392
            else
1393
              set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
1394
          }
1395
        break;
1396
      }
1397
 
1398
    case TYPE_POINTER:
1399
      set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
1400
      break;
1401
 
1402
    case TYPE_ARRAY:
1403
      set_gc_used_type (t->u.a.p, GC_USED, param);
1404
      break;
1405
 
1406
    case TYPE_LANG_STRUCT:
1407
      for (t = t->u.s.lang_struct; t; t = t->next)
1408
        set_gc_used_type (t, level, param);
1409
      break;
1410
 
1411
    case TYPE_PARAM_STRUCT:
1412
      {
1413
        int i;
1414
        for (i = 0; i < NUM_PARAM; i++)
1415
          if (t->u.param_struct.param[i] != 0)
1416
            set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
1417
      }
1418
      if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
1419
        level = GC_POINTED_TO;
1420
      else
1421
        level = GC_USED;
1422
      t->u.param_struct.stru->gc_used = GC_UNUSED;
1423
      set_gc_used_type (t->u.param_struct.stru, level,
1424
                        t->u.param_struct.param);
1425
      break;
1426
 
1427
    default:
1428
      break;
1429
    }
1430
}
1431
 
1432
/* Set the gc_used fields of all the types pointed to by VARIABLES.  */
1433
 
1434
static void
1435
set_gc_used (pair_p variables)
1436
{
1437
  int nbvars = 0;
1438
  pair_p p;
1439
  for (p = variables; p; p = p->next)
1440
    {
1441
      set_gc_used_type (p->type, GC_USED, NULL);
1442
      nbvars++;
1443
    };
1444
  if (verbosity_level >= 2)
1445
    printf ("%s used %d GTY-ed variables\n", progname, nbvars);
1446
}
1447
 
1448
/* File mapping routines.  For each input file, there is one output .c file
1449
   (but some output files have many input files), and there is one .h file
1450
   for the whole build.  */
1451
 
1452
/* Output file handling.  */
1453
 
1454
/* Create and return an outf_p for a new file for NAME, to be called
1455
   ONAME.  */
1456
 
1457
static outf_p
1458
create_file (const char *name, const char *oname)
1459
{
1460
  static const char *const hdr[] = {
1461
    "   Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.\n",
1462
    "\n",
1463
    "This file is part of GCC.\n",
1464
    "\n",
1465
    "GCC is free software; you can redistribute it and/or modify it under\n",
1466
    "the terms of the GNU General Public License as published by the Free\n",
1467
    "Software Foundation; either version 3, or (at your option) any later\n",
1468
    "version.\n",
1469
    "\n",
1470
    "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1471
    "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1472
    "FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n",
1473
    "for more details.\n",
1474
    "\n",
1475
    "You should have received a copy of the GNU General Public License\n",
1476
    "along with GCC; see the file COPYING3.  If not see\n",
1477
    "<http://www.gnu.org/licenses/>.  */\n",
1478
    "\n",
1479
    "/* This file is machine generated.  Do not edit.  */\n"
1480
  };
1481
  outf_p f;
1482
  size_t i;
1483
 
1484
  gcc_assert (name != NULL);
1485
  gcc_assert (oname != NULL);
1486
  f = XCNEW (struct outf);
1487
  f->next = output_files;
1488
  f->name = oname;
1489
  output_files = f;
1490
 
1491
  oprintf (f, "/* Type information for %s.\n", name);
1492
  for (i = 0; i < ARRAY_SIZE (hdr); i++)
1493
    oprintf (f, "%s", hdr[i]);
1494
  return f;
1495
}
1496
 
1497
/* Print, like fprintf, to O.
1498
   N.B. You might think this could be implemented more efficiently
1499
   with vsnprintf().  Unfortunately, there are C libraries that
1500
   provide that function but without the C99 semantics for its return
1501
   value, making it impossible to know how much space is required.  */
1502
void
1503
oprintf (outf_p o, const char *format, ...)
1504
{
1505
  char *s;
1506
  size_t slength;
1507
  va_list ap;
1508
 
1509
  /* In plugin mode, the O could be a NULL pointer, so avoid crashing
1510
     in that case.  */
1511
  if (!o)
1512
    return;
1513
 
1514
  va_start (ap, format);
1515
  slength = vasprintf (&s, format, ap);
1516
  if (s == NULL || (int) slength < 0)
1517
    fatal ("out of memory");
1518
  va_end (ap);
1519
 
1520
  if (o->bufused + slength > o->buflength)
1521
    {
1522
      size_t new_len = o->buflength;
1523
      if (new_len == 0)
1524
        new_len = 1024;
1525
      do
1526
        {
1527
          new_len *= 2;
1528
        }
1529
      while (o->bufused + slength >= new_len);
1530
      o->buf = XRESIZEVEC (char, o->buf, new_len);
1531
      o->buflength = new_len;
1532
    }
1533
  memcpy (o->buf + o->bufused, s, slength);
1534
  o->bufused += slength;
1535
  free (s);
1536
}
1537
 
1538
/* Open the global header file and the language-specific header files.  */
1539
 
1540
static void
1541
open_base_files (void)
1542
{
1543
  size_t i;
1544
 
1545
  if (nb_plugin_files > 0 && plugin_files)
1546
    return;
1547
 
1548
  header_file = create_file ("GCC", "gtype-desc.h");
1549
 
1550
  base_files = XNEWVEC (outf_p, num_lang_dirs);
1551
 
1552
  for (i = 0; i < num_lang_dirs; i++)
1553
    base_files[i] = create_file (lang_dir_names[i],
1554
                                 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1555
 
1556
  /* gtype-desc.c is a little special, so we create it here.  */
1557
  {
1558
    /* The order of files here matters very much.  */
1559
    static const char *const ifiles[] = {
1560
      "config.h", "system.h", "coretypes.h", "tm.h",
1561
      "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1562
      "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1563
      "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1564
      "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1565
      "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1566
      "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
1567
      "target.h", "ipa-prop.h", "lto-streamer.h", "target-globals.h",
1568
      "ipa-inline.h", "dwarf2out.h", NULL
1569
    };
1570
    const char *const *ifp;
1571
    outf_p gtype_desc_c;
1572
 
1573
    gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1574
    for (ifp = ifiles; *ifp; ifp++)
1575
      oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1576
 
1577
    /* Make sure we handle "cfun" specially.  */
1578
    oprintf (gtype_desc_c, "\n/* See definition in function.h.  */\n");
1579
    oprintf (gtype_desc_c, "#undef cfun\n");
1580
  }
1581
}
1582
 
1583
/* For INPF an input file, return the real basename of INPF, with all
1584
   the directory components skipped.  */
1585
 
1586
static const char *
1587
get_file_realbasename (const input_file *inpf)
1588
{
1589
  return lbasename (get_input_file_name (inpf));
1590
}
1591
 
1592
/* For INPF a filename, return the relative path to INPF from
1593
   $(srcdir) if the latter is a prefix in INPF, NULL otherwise.  */
1594
 
1595
const char *
1596
get_file_srcdir_relative_path (const input_file *inpf)
1597
{
1598
  const char *f = get_input_file_name (inpf);
1599
  if (strlen (f) > srcdir_len
1600
      && IS_DIR_SEPARATOR (f[srcdir_len])
1601
      && strncmp (f, srcdir, srcdir_len) == 0)
1602
    return f + srcdir_len + 1;
1603
  else
1604
    return NULL;
1605
}
1606
 
1607
/*  For INPF an input_file, return the relative path to INPF from
1608
    $(srcdir) if the latter is a prefix in INPF, or the real basename
1609
    of INPF otherwise. */
1610
 
1611
static const char *
1612
get_file_basename (const input_file *inpf)
1613
{
1614
  const char *srcdir_path = get_file_srcdir_relative_path (inpf);
1615
 
1616
  return (srcdir_path != NULL) ? srcdir_path : get_file_realbasename (inpf);
1617
}
1618
 
1619
/* For F a filename, return the lang_dir_names relative index of the language
1620
   directory that is a prefix in F, if any, -1 otherwise.  */
1621
 
1622
static int
1623
get_prefix_langdir_index (const char *f)
1624
{
1625
  size_t f_len = strlen (f);
1626
  size_t lang_index;
1627
 
1628
  for (lang_index = 0; lang_index < num_lang_dirs; lang_index++)
1629
    {
1630
      const char *langdir = lang_dir_names[lang_index];
1631
      size_t langdir_len = strlen (langdir);
1632
 
1633
      if (f_len > langdir_len
1634
          && IS_DIR_SEPARATOR (f[langdir_len])
1635
          && memcmp (f, langdir, langdir_len) == 0)
1636
        return lang_index;
1637
    }
1638
 
1639
  return -1;
1640
}
1641
 
1642
/* For INPF an input file, return the name of language directory where
1643
   F is located, if any, NULL otherwise.  */
1644
 
1645
static const char *
1646
get_file_langdir (const input_file *inpf)
1647
{
1648
  /* Get the relative path to INPF from $(srcdir) and find the
1649
     language by comparing the prefix with language directory names.
1650
     If INPF is not even srcdir relative, no point in looking
1651
     further.  */
1652
 
1653
  int lang_index;
1654
  const char *srcdir_relative_path = get_file_srcdir_relative_path (inpf);
1655
  const char *r;
1656
 
1657
  if (!srcdir_relative_path)
1658
    return NULL;
1659
 
1660
  lang_index = get_prefix_langdir_index (srcdir_relative_path);
1661
  if (lang_index < 0 && strncmp (srcdir_relative_path, "c-family", 8) == 0)
1662
    r = "c-family";
1663
  else if (lang_index >= 0)
1664
    r = lang_dir_names[lang_index];
1665
  else
1666
    r = NULL;
1667
 
1668
  return r;
1669
}
1670
 
1671
/* The gt- output file name for INPF.  */
1672
 
1673
static const char *
1674
get_file_gtfilename (const input_file *inpf)
1675
{
1676
  /* Cook up an initial version of the gt- file name from the file real
1677
     basename and the language name, if any.  */
1678
 
1679
  const char *basename = get_file_realbasename (inpf);
1680
  const char *langdir = get_file_langdir (inpf);
1681
 
1682
  char *result =
1683
    (langdir ? xasprintf ("gt-%s-%s", langdir, basename)
1684
     : xasprintf ("gt-%s", basename));
1685
 
1686
  /* Then replace all non alphanumerics characters by '-' and change the
1687
     extension to ".h".  We expect the input filename extension was at least
1688
     one character long.  */
1689
 
1690
  char *s = result;
1691
 
1692
  for (; *s != '.'; s++)
1693
    if (!ISALNUM (*s) && *s != '-')
1694
      *s = '-';
1695
 
1696
  memcpy (s, ".h", sizeof (".h"));
1697
 
1698
  return result;
1699
}
1700
 
1701
/* Each input_file has its associated output file outf_p.  The
1702
   association is computed by the function
1703
   get_output_file_with_visibility.  The associated file is cached
1704
   inside input_file in its inpoutf field, so is really computed only
1705
   once.  Associated output file paths (i.e. output_name-s) are
1706
   computed by a rule based regexp machinery, using the files_rules
1707
   array of struct file_rule_st.  A for_name is also computed, giving
1708
   the source file name for which the output_file is generated; it is
1709
   often the last component of the input_file path.  */
1710
 
1711
 
1712
/*
1713
 Regexpr machinery to compute the output_name and for_name-s of each
1714
 input_file.  We have a sequence of file rules which gives the POSIX
1715
 extended regular expression to match an input file path, and two
1716
 transformed strings for the corresponding output_name and the
1717
 corresponding for_name.  The transformed string contain dollars: $0
1718
 is replaced by the entire match, $1 is replaced by the substring
1719
 matching the first parenthesis in the regexp, etc.  And $$ is replaced
1720
 by a single verbatim dollar.  The rule order is important.  The
1721
 general case is last, and the particular cases should come before.
1722
 An action routine can, when needed, update the out_name & for_name
1723
 and/or return the appropriate output file.  It is invoked only when a
1724
 rule is triggered.  When a rule is triggered, the output_name and
1725
 for_name are computed using their transform string in while $$, $0,
1726
 $1, ... are suitably replaced.  If there is an action, it is called.
1727
 In some few cases, the action can directly return the outf_p, but
1728
 usually it just updates the output_name and for_name so should free
1729
 them before replacing them.  The get_output_file_with_visibility
1730
 function creates an outf_p only once per each output_name, so it
1731
 scans the output_files list for previously seen output file names.
1732
 */
1733
 
1734
/* Signature of actions in file rules.  */
1735
typedef outf_p (frul_actionrout_t) (input_file*, char**, char**);
1736
 
1737
 
1738
struct file_rule_st {
1739
  const char* frul_srcexpr;     /* Source string for regexp.  */
1740
  int frul_rflags;              /* Flags passed to regcomp, usually
1741
                                 * REG_EXTENDED.  */
1742
  regex_t* frul_re;             /* Compiled regular expression
1743
                                   obtained by regcomp.  */
1744
  const char* frul_tr_out;      /* Transformation string for making
1745
                                 * the output_name, with $1 ... $9 for
1746
                                 * subpatterns and $0 for the whole
1747
                                 * matched filename.  */
1748
  const char* frul_tr_for;      /* Tranformation string for making the
1749
                                   for_name.  */
1750
  frul_actionrout_t* frul_action; /* The action, if non null, is
1751
                                   * called once the rule matches, on
1752
                                   * the transformed out_name &
1753
                                   * for_name.  It could change them
1754
                                   * and/or give the output file.  */
1755
};
1756
 
1757
/* File rule action handling *.h files.  */
1758
static outf_p header_dot_h_frul (input_file*, char**, char**);
1759
 
1760
/* File rule action handling *.c files.  */
1761
static outf_p source_dot_c_frul (input_file*, char**, char**);
1762
 
1763
#define NULL_REGEX (regex_t*)0
1764
 
1765
/* The prefix in our regexp-s matching the directory.  */
1766
#define DIR_PREFIX_REGEX "^(([^/]*/)*)"
1767
 
1768
#define NULL_FRULACT (frul_actionrout_t*)0
1769
 
1770
/* The array of our rules governing file name generation.  Rules order
1771
   matters, so change with extreme care!  */
1772
 
1773
struct file_rule_st files_rules[] = {
1774
  /* The general rule assumes that files in subdirectories belong to a
1775
     particular front-end, and files not in subdirectories are shared.
1776
     The following rules deal with exceptions - files that are in
1777
     subdirectories and yet are shared, and files that are top-level,
1778
     but are not shared.  */
1779
 
1780
  /* the c-family/ source directory is special.  */
1781
  { DIR_PREFIX_REGEX "c-family/([[:alnum:]_-]*)\\.c$",
1782
    REG_EXTENDED, NULL_REGEX,
1783
    "gt-c-family-$3.h", "c-family/$3.c", NULL_FRULACT},
1784
 
1785
  { DIR_PREFIX_REGEX "c-family/([[:alnum:]_-]*)\\.h$",
1786
    REG_EXTENDED, NULL_REGEX,
1787
    "gt-c-family-$3.h", "c-family/$3.h", NULL_FRULACT},
1788
 
1789
  /* Both c-lang.h & c-tree.h gives gt-c-decl.h for c-decl.c !  */
1790
  { DIR_PREFIX_REGEX "c-lang\\.h$",
1791
    REG_EXTENDED, NULL_REGEX, "gt-c-decl.h", "c-decl.c", NULL_FRULACT},
1792
 
1793
  { DIR_PREFIX_REGEX "c-tree\\.h$",
1794
    REG_EXTENDED, NULL_REGEX, "gt-c-decl.h", "c-decl.c", NULL_FRULACT},
1795
 
1796
  /* cp/cp-tree.h gives gt-cp-tree.h for cp/tree.c !  */
1797
  { DIR_PREFIX_REGEX "cp/cp-tree\\.h$",
1798
    REG_EXTENDED, NULL_REGEX,
1799
    "gt-cp-tree.h", "cp/tree.c", NULL_FRULACT },
1800
 
1801
  /* cp/decl.h & cp/decl.c gives gt-cp-decl.h for cp/decl.c !  */
1802
  { DIR_PREFIX_REGEX "cp/decl\\.[ch]$",
1803
    REG_EXTENDED, NULL_REGEX,
1804
    "gt-cp-decl.h", "cp/decl.c", NULL_FRULACT },
1805
 
1806
  /* cp/name-lookup.h gives gt-cp-name-lookup.h for cp/name-lookup.c !  */
1807
  { DIR_PREFIX_REGEX "cp/name-lookup\\.h$",
1808
    REG_EXTENDED, NULL_REGEX,
1809
    "gt-cp-name-lookup.h", "cp/name-lookup.c", NULL_FRULACT },
1810
 
1811
  /* cp/parser.h gives gt-cp-parser.h for cp/parser.c !  */
1812
  { DIR_PREFIX_REGEX "cp/parser\\.h$",
1813
    REG_EXTENDED, NULL_REGEX,
1814
    "gt-cp-parser.h", "cp/parser.c", NULL_FRULACT },
1815
 
1816
  /* objc/objc-act.h gives gt-objc-objc-act.h for objc/objc-act.c !  */
1817
  { DIR_PREFIX_REGEX "objc/objc-act\\.h$",
1818
    REG_EXTENDED, NULL_REGEX,
1819
    "gt-objc-objc-act.h", "objc/objc-act.c", NULL_FRULACT },
1820
 
1821
  /* objc/objc-map.h gives gt-objc-objc-map.h for objc/objc-map.c !  */
1822
  { DIR_PREFIX_REGEX "objc/objc-map\\.h$",
1823
    REG_EXTENDED, NULL_REGEX,
1824
    "gt-objc-objc-map.h", "objc/objc-map.c", NULL_FRULACT },
1825
 
1826
  /* General cases.  For header *.h and source *.c files, we need
1827
   * special actions to handle the language.  */
1828
 
1829
  /* Source *.c files are using get_file_gtfilename to compute their
1830
     output_name and get_file_basename to compute their for_name
1831
     thru the source_dot_c_frul action.  */
1832
  { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.c$",
1833
    REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.c", source_dot_c_frul},
1834
  /* Common header files get "gtype-desc.c" as their output_name,
1835
   * while language specific header files are handled specially.  So
1836
   * we need the header_dot_h_frul action.  */
1837
  { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.h$",
1838
    REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.h", header_dot_h_frul},
1839
 
1840
  { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.in$",
1841
    REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.in", NULL_FRULACT},
1842
 
1843
  /* Mandatory null last entry signaling end of rules.  */
1844
  {NULL, 0, NULL_REGEX, NULL, NULL, NULL_FRULACT}
1845
};
1846
 
1847
/* Special file rules action for handling *.h header files.  It gives
1848
   "gtype-desc.c" for common headers and corresponding output
1849
   files for language-specific header files.  */
1850
static outf_p
1851
header_dot_h_frul (input_file* inpf, char**poutname,
1852
                   char**pforname ATTRIBUTE_UNUSED)
1853
{
1854
  const char *basename = 0;
1855
  int lang_index = 0;
1856
  DBGPRINTF ("inpf %p inpname %s outname %s forname %s",
1857
             (void*) inpf, get_input_file_name (inpf),
1858
             *poutname, *pforname);
1859
  basename = get_file_basename (inpf);
1860
  lang_index = get_prefix_langdir_index (basename);
1861
  DBGPRINTF ("basename %s lang_index %d", basename, lang_index);
1862
 
1863
  if (lang_index >= 0)
1864
    {
1865
      /* The header is language specific.  Given output_name &
1866
         for_name remains unchanged.  The base_files array gives the
1867
         outf_p.  */
1868
      DBGPRINTF ("header_dot_h found language specific @ %p '%s'",
1869
                 (void*) base_files[lang_index],
1870
                 (base_files[lang_index])->name);
1871
      return base_files[lang_index];
1872
    }
1873
  else
1874
    {
1875
      /* The header is common to all front-end languages.  So
1876
         output_name is "gtype-desc.c" file.  The calling function
1877
         get_output_file_with_visibility will find its outf_p.  */
1878
      free (*poutname);
1879
      *poutname = xstrdup ("gtype-desc.c");
1880
      DBGPRINTF ("special 'gtype-desc.c' for inpname %s",
1881
                 get_input_file_name (inpf));
1882
      return NULL;
1883
    }
1884
}
1885
 
1886
 
1887
/* Special file rules action for handling *.c source files using
1888
 * get_file_gtfilename to compute their output_name and
1889
 * get_file_basename to compute their for_name.  The output_name is
1890
 * gt-<LANG>-<BASE>.h for language specific source files, and
1891
 * gt-<BASE>.h for common source files.  */
1892
static outf_p
1893
source_dot_c_frul (input_file* inpf, char**poutname, char**pforname)
1894
{
1895
  char *newbasename = CONST_CAST (char*, get_file_basename (inpf));
1896
  char *newoutname = CONST_CAST (char*, get_file_gtfilename (inpf));
1897
  DBGPRINTF ("inpf %p inpname %s original outname %s forname %s",
1898
             (void*) inpf, get_input_file_name (inpf),
1899
             *poutname, *pforname);
1900
  DBGPRINTF ("newoutname %s", newoutname);
1901
  DBGPRINTF ("newbasename %s", newbasename);
1902
  free (*poutname);
1903
  free (*pforname);
1904
  *poutname = newoutname;
1905
  *pforname = newbasename;
1906
  return NULL;
1907
}
1908
 
1909
/* Utility function for get_output_file_with_visibility which returns
1910
 * a malloc-ed substituted string using TRS on matching of the FILNAM
1911
 * file name, using the PMATCH array.  */
1912
static char*
1913
matching_file_name_substitute (const char *filnam, regmatch_t pmatch[10],
1914
                               const char *trs)
1915
{
1916
  struct obstack str_obstack;
1917
  char *str = NULL;
1918
  char *rawstr = NULL;
1919
  const char *pt = NULL;
1920
  DBGPRINTF ("filnam %s", filnam);
1921
  obstack_init (&str_obstack);
1922
  for (pt = trs; *pt; pt++) {
1923
    char c = *pt;
1924
    if (c == '$')
1925
      {
1926
        if (pt[1] == '$')
1927
          {
1928
            /* A double dollar $$ is substituted by a single verbatim
1929
               dollar, but who really uses dollar signs in file
1930
               paths? */
1931
            obstack_1grow (&str_obstack, '$');
1932
          }
1933
        else if (ISDIGIT (pt[1]))
1934
          {
1935
            /* Handle $0 $1 ... $9 by appropriate substitution.  */
1936
            int dolnum = pt[1] - '0';
1937
            int so = pmatch[dolnum].rm_so;
1938
            int eo = pmatch[dolnum].rm_eo;
1939
            DBGPRINTF ("so=%d eo=%d dolnum=%d", so, eo, dolnum);
1940
            if (so>=0 && eo>=so)
1941
              obstack_grow (&str_obstack, filnam + so, eo - so);
1942
          }
1943
        else
1944
          {
1945
            /* This can happen only when files_rules is buggy! */
1946
            gcc_unreachable();
1947
          }
1948
        /* Always skip the character after the dollar.  */
1949
        pt++;
1950
      }
1951
    else
1952
      obstack_1grow (&str_obstack, c);
1953
  }
1954
  obstack_1grow (&str_obstack, '\0');
1955
  rawstr = XOBFINISH (&str_obstack, char *);
1956
  str = xstrdup (rawstr);
1957
  obstack_free (&str_obstack, NULL);
1958
  DBGPRINTF ("matched replacement %s", str);
1959
  rawstr = NULL;
1960
  return str;
1961
}
1962
 
1963
 
1964
/* An output file, suitable for definitions, that can see declarations
1965
   made in INPF and is linked into every language that uses INPF.
1966
   Since the result is cached inside INPF, that argument cannot be
1967
   declared constant, but is "almost" constant. */
1968
 
1969
outf_p
1970
get_output_file_with_visibility (input_file *inpf)
1971
{
1972
  outf_p r;
1973
  char *for_name = NULL;
1974
  char *output_name = NULL;
1975
  const char* inpfname;
1976
 
1977
  /* This can happen when we need a file with visibility on a
1978
     structure that we've never seen.  We have to just hope that it's
1979
     globally visible.  */
1980
  if (inpf == NULL)
1981
    inpf = system_h_file;
1982
 
1983
  /* The result is cached in INPF, so return it if already known.  */
1984
  if (inpf->inpoutf)
1985
    return inpf->inpoutf;
1986
 
1987
  /* In plugin mode, return NULL unless the input_file is one of the
1988
     plugin_files.  */
1989
  if (plugin_files)
1990
    {
1991
      size_t i;
1992
      for (i = 0; i < nb_plugin_files; i++)
1993
        if (inpf == plugin_files[i])
1994
          {
1995
            inpf->inpoutf = plugin_output;
1996
            return plugin_output;
1997
          }
1998
 
1999
      return NULL;
2000
    }
2001
 
2002
  inpfname = get_input_file_name (inpf);
2003
 
2004
  /* Try each rule in sequence in files_rules until one is triggered. */
2005
  {
2006
    int rulix = 0;
2007
    DBGPRINTF ("passing input file @ %p named %s thru the files_rules",
2008
               (void*) inpf, inpfname);
2009
 
2010
    for (; files_rules[rulix].frul_srcexpr != NULL; rulix++)
2011
      {
2012
        DBGPRINTF ("rulix#%d srcexpr %s",
2013
                   rulix, files_rules[rulix].frul_srcexpr);
2014
 
2015
        if (!files_rules[rulix].frul_re)
2016
          {
2017
            /* Compile the regexpr lazily.  */
2018
            int err = 0;
2019
            files_rules[rulix].frul_re = XCNEW (regex_t);
2020
            err = regcomp (files_rules[rulix].frul_re,
2021
                           files_rules[rulix].frul_srcexpr,
2022
                           files_rules[rulix].frul_rflags);
2023
            if (err)
2024
              {
2025
                /* The regular expression compilation fails only when
2026
                   file_rules is buggy.  */
2027
                gcc_unreachable ();
2028
              }
2029
          }
2030
 
2031
        output_name = NULL;
2032
        for_name = NULL;
2033
 
2034
        /* Match the regexpr and trigger the rule if matched.  */
2035
        {
2036
          /* We have exactly ten pmatch-s, one for each $0, $1, $2,
2037
             $3, ... $9.  */
2038
          regmatch_t pmatch[10];
2039
          memset (pmatch, 0, sizeof (pmatch));
2040
          if (!regexec (files_rules[rulix].frul_re,
2041
                        inpfname, 10, pmatch, 0))
2042
            {
2043
              DBGPRINTF ("input @ %p filename %s matched rulix#%d pattern %s",
2044
                         (void*) inpf, inpfname, rulix,
2045
                         files_rules[rulix].frul_srcexpr);
2046
              for_name =
2047
                matching_file_name_substitute (inpfname, pmatch,
2048
                                               files_rules[rulix].frul_tr_for);
2049
              DBGPRINTF ("for_name %s", for_name);
2050
              output_name =
2051
                matching_file_name_substitute (inpfname, pmatch,
2052
                                               files_rules[rulix].frul_tr_out);
2053
              DBGPRINTF ("output_name %s", output_name);
2054
              if (files_rules[rulix].frul_action)
2055
                {
2056
                  /* Invoke our action routine.  */
2057
                  outf_p of = NULL;
2058
                  DBGPRINTF ("before action rulix#%d output_name %s for_name %s",
2059
                             rulix, output_name, for_name);
2060
                  of =
2061
                    (files_rules[rulix].frul_action) (inpf,
2062
                                                      &output_name, &for_name);
2063
                  DBGPRINTF ("after action rulix#%d of=%p output_name %s for_name %s",
2064
                             rulix, (void*)of, output_name, for_name);
2065
                  /* If the action routine returned something, give it back
2066
                     immediately and cache it in inpf.  */
2067
                  if (of)
2068
                    {
2069
                      inpf->inpoutf = of;
2070
                      return of;
2071
                    }
2072
                }
2073
              /* The rule matched, and had no action, or that action did
2074
                 not return any output file but could have changed the
2075
                 output_name or for_name.  We break out of the loop on the
2076
                 files_rules.  */
2077
              break;
2078
            }
2079
          else
2080
            {
2081
              /* The regexpr did not match.  */
2082
              DBGPRINTF ("rulix#%d did not match %s pattern %s",
2083
                         rulix, inpfname, files_rules[rulix].frul_srcexpr);
2084
              continue;
2085
            }
2086
        }
2087
      }
2088
  }
2089
  if (!output_name || !for_name)
2090
    {
2091
      /* This is impossible, and could only happen if the files_rules is
2092
         incomplete or buggy.  */
2093
      gcc_unreachable ();
2094
    }
2095
 
2096
  /* Look through to see if we've ever seen this output filename
2097
     before.  If found, cache the result in inpf.  */
2098
  for (r = output_files; r; r = r->next)
2099
    if (filename_cmp (r->name, output_name) == 0)
2100
      {
2101
        inpf->inpoutf = r;
2102
        DBGPRINTF ("found r @ %p for output_name %s for_name %s", (void*)r,
2103
                   output_name, for_name);
2104
        return r;
2105
      }
2106
 
2107
  /* If not found, create it, and cache it in inpf.  */
2108
  r = create_file (for_name, output_name);
2109
 
2110
  gcc_assert (r && r->name);
2111
  DBGPRINTF ("created r @ %p for output_name %s for_name %s", (void*) r,
2112
             output_name, for_name);
2113
  inpf->inpoutf = r;
2114
  return r;
2115
 
2116
 
2117
}
2118
 
2119
/* The name of an output file, suitable for definitions, that can see
2120
   declarations made in INPF and is linked into every language that
2121
   uses INPF.  */
2122
 
2123
const char *
2124
get_output_file_name (input_file* inpf)
2125
{
2126
  outf_p o = get_output_file_with_visibility (inpf);
2127
  if (o)
2128
    return o->name;
2129
  return NULL;
2130
}
2131
 
2132
/* Check if existing file is equal to the in memory buffer. */
2133
 
2134
static bool
2135
is_file_equal (outf_p of)
2136
{
2137
  FILE *newfile = fopen (of->name, "r");
2138
  size_t i;
2139
  bool equal;
2140
  if (newfile == NULL)
2141
    return false;
2142
 
2143
  equal = true;
2144
  for (i = 0; i < of->bufused; i++)
2145
    {
2146
      int ch;
2147
      ch = fgetc (newfile);
2148
      if (ch == EOF || ch != (unsigned char) of->buf[i])
2149
        {
2150
          equal = false;
2151
          break;
2152
        }
2153
    }
2154
  fclose (newfile);
2155
  return equal;
2156
}
2157
 
2158
/* Copy the output to its final destination,
2159
   but don't unnecessarily change modification times.  */
2160
 
2161
static void
2162
close_output_files (void)
2163
{
2164
  int nbwrittenfiles = 0;
2165
  outf_p of;
2166
 
2167
  for (of = output_files; of; of = of->next)
2168
    {
2169
 
2170
      if (!is_file_equal (of))
2171
        {
2172
          FILE *newfile = NULL;
2173
          char *backupname = NULL;
2174
          /* Back up the old version of the output file gt-FOO.c as
2175
             BACKUPDIR/gt-FOO.c~ if we have a backup directory.  */
2176
          if (backup_dir)
2177
            {
2178
              backupname = concat (backup_dir, "/",
2179
                                   lbasename (of->name), "~", NULL);
2180
              if (!access (of->name, F_OK) && rename (of->name, backupname))
2181
                fatal ("failed to back up %s as %s: %s",
2182
                       of->name, backupname, xstrerror (errno));
2183
            }
2184
 
2185
          newfile = fopen (of->name, "w");
2186
          if (newfile == NULL)
2187
            fatal ("opening output file %s: %s", of->name, xstrerror (errno));
2188
          if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
2189
            fatal ("writing output file %s: %s", of->name, xstrerror (errno));
2190
          if (fclose (newfile) != 0)
2191
            fatal ("closing output file %s: %s", of->name, xstrerror (errno));
2192
          nbwrittenfiles++;
2193
          if (verbosity_level >= 2 && backupname)
2194
            printf ("%s wrote #%-3d %s backed-up in %s\n",
2195
                    progname, nbwrittenfiles, of->name, backupname);
2196
          else if (verbosity_level >= 1)
2197
            printf ("%s write #%-3d %s\n", progname, nbwrittenfiles, of->name);
2198
          free (backupname);
2199
        }
2200
      else
2201
        {
2202
          /* output file remains unchanged. */
2203
          if (verbosity_level >= 2)
2204
            printf ("%s keep %s\n", progname, of->name);
2205
        }
2206
      free (of->buf);
2207
      of->buf = NULL;
2208
      of->bufused = of->buflength = 0;
2209
    }
2210
  if (verbosity_level >= 1)
2211
    printf ("%s wrote %d files.\n", progname, nbwrittenfiles);
2212
}
2213
 
2214
struct flist
2215
{
2216
  struct flist *next;
2217
  int started_p;
2218
  const input_file* file;
2219
  outf_p f;
2220
};
2221
 
2222
struct walk_type_data;
2223
 
2224
/* For scalars and strings, given the item in 'val'.
2225
   For structures, given a pointer to the item in 'val'.
2226
   For misc. pointers, given the item in 'val'.
2227
*/
2228
typedef void (*process_field_fn) (type_p f, const struct walk_type_data * p);
2229
typedef void (*func_name_fn) (type_p s, const struct walk_type_data * p);
2230
 
2231
/* Parameters for write_types.  */
2232
 
2233
struct write_types_data
2234
{
2235
  const char *prefix;
2236
  const char *param_prefix;
2237
  const char *subfield_marker_routine;
2238
  const char *marker_routine;
2239
  const char *reorder_note_routine;
2240
  const char *comment;
2241
  int skip_hooks;               /* skip hook generation if non zero */
2242
};
2243
 
2244
static void output_escaped_param (struct walk_type_data *d,
2245
                                  const char *, const char *);
2246
static void output_mangled_typename (outf_p, const_type_p);
2247
static void walk_type (type_p t, struct walk_type_data *d);
2248
static void write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2249
                                      const struct write_types_data *wtd);
2250
static void write_types_process_field
2251
  (type_p f, const struct walk_type_data *d);
2252
static void write_types (outf_p output_header,
2253
                         type_p structures,
2254
                         type_p param_structs,
2255
                         const struct write_types_data *wtd);
2256
static void write_types_local_process_field
2257
  (type_p f, const struct walk_type_data *d);
2258
static void write_local_func_for_structure
2259
  (const_type_p orig_s, type_p s, type_p *param);
2260
static void write_local (outf_p output_header,
2261
                         type_p structures, type_p param_structs);
2262
static void write_enum_defn (type_p structures, type_p param_structs);
2263
static int contains_scalar_p (type_p t);
2264
static void put_mangled_filename (outf_p, const input_file *);
2265
static void finish_root_table (struct flist *flp, const char *pfx,
2266
                               const char *tname, const char *lastname,
2267
                               const char *name);
2268
static void write_root (outf_p, pair_p, type_p, const char *, int,
2269
                        struct fileloc *, const char *, bool);
2270
static void write_array (outf_p f, pair_p v,
2271
                         const struct write_types_data *wtd);
2272
static void write_roots (pair_p, bool);
2273
 
2274
/* Parameters for walk_type.  */
2275
 
2276
struct walk_type_data
2277
{
2278
  process_field_fn process_field;
2279
  const void *cookie;
2280
  outf_p of;
2281
  options_p opt;
2282
  const char *val;
2283
  const char *prev_val[4];
2284
  int indent;
2285
  int counter;
2286
  const struct fileloc *line;
2287
  lang_bitmap bitmap;
2288
  type_p *param;
2289
  int used_length;
2290
  type_p orig_s;
2291
  const char *reorder_fn;
2292
  bool needs_cast_p;
2293
  bool fn_wants_lvalue;
2294
};
2295
 
2296
/* Print a mangled name representing T to OF.  */
2297
 
2298
static void
2299
output_mangled_typename (outf_p of, const_type_p t)
2300
{
2301
  if (t == NULL)
2302
    oprintf (of, "Z");
2303
  else
2304
    switch (t->kind)
2305
      {
2306
      case TYPE_NONE:
2307
        gcc_unreachable ();
2308
        break;
2309
      case TYPE_POINTER:
2310
        oprintf (of, "P");
2311
        output_mangled_typename (of, t->u.p);
2312
        break;
2313
      case TYPE_SCALAR:
2314
        oprintf (of, "I");
2315
        break;
2316
      case TYPE_STRING:
2317
        oprintf (of, "S");
2318
        break;
2319
      case TYPE_STRUCT:
2320
      case TYPE_UNION:
2321
      case TYPE_LANG_STRUCT:
2322
        oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag),
2323
                 t->u.s.tag);
2324
        break;
2325
      case TYPE_PARAM_STRUCT:
2326
        {
2327
          int i;
2328
          for (i = 0; i < NUM_PARAM; i++)
2329
            if (t->u.param_struct.param[i] != NULL)
2330
              output_mangled_typename (of, t->u.param_struct.param[i]);
2331
          output_mangled_typename (of, t->u.param_struct.stru);
2332
        }
2333
        break;
2334
      case TYPE_ARRAY:
2335
        gcc_unreachable ();
2336
      }
2337
}
2338
 
2339
/* Print PARAM to D->OF processing escapes.  D->VAL references the
2340
   current object, D->PREV_VAL the object containing the current
2341
   object, ONAME is the name of the option and D->LINE is used to
2342
   print error messages.  */
2343
 
2344
static void
2345
output_escaped_param (struct walk_type_data *d, const char *param,
2346
                      const char *oname)
2347
{
2348
  const char *p;
2349
 
2350
  for (p = param; *p; p++)
2351
    if (*p != '%')
2352
      oprintf (d->of, "%c", *p);
2353
    else
2354
      switch (*++p)
2355
        {
2356
        case 'h':
2357
          oprintf (d->of, "(%s)", d->prev_val[2]);
2358
          break;
2359
        case '0':
2360
          oprintf (d->of, "(%s)", d->prev_val[0]);
2361
          break;
2362
        case '1':
2363
          oprintf (d->of, "(%s)", d->prev_val[1]);
2364
          break;
2365
        case 'a':
2366
          {
2367
            const char *pp = d->val + strlen (d->val);
2368
            while (pp[-1] == ']')
2369
              while (*pp != '[')
2370
                pp--;
2371
            oprintf (d->of, "%s", pp);
2372
          }
2373
          break;
2374
        default:
2375
          error_at_line (d->line, "`%s' option contains bad escape %c%c",
2376
                         oname, '%', *p);
2377
        }
2378
}
2379
 
2380
/* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
2381
   which is of type T.  Write code to D->OF to constrain execution (at
2382
   the point that D->PROCESS_FIELD is called) to the appropriate
2383
   cases.  Call D->PROCESS_FIELD on subobjects before calling it on
2384
   pointers to those objects.  D->PREV_VAL lists the objects
2385
   containing the current object, D->OPT is a list of options to
2386
   apply, D->INDENT is the current indentation level, D->LINE is used
2387
   to print error messages, D->BITMAP indicates which languages to
2388
   print the structure for, and D->PARAM is the current parameter
2389
   (from an enclosing param_is option).  */
2390
 
2391
static void
2392
walk_type (type_p t, struct walk_type_data *d)
2393
{
2394
  const char *length = NULL;
2395
  const char *desc = NULL;
2396
  int maybe_undef_p = 0;
2397
  int use_param_num = -1;
2398
  int use_params_p = 0;
2399
  int atomic_p = 0;
2400
  options_p oo;
2401
  const struct nested_ptr_data *nested_ptr_d = NULL;
2402
 
2403
  d->needs_cast_p = false;
2404
  for (oo = d->opt; oo; oo = oo->next)
2405
    if (strcmp (oo->name, "length") == 0 && oo->kind == OPTION_STRING)
2406
      length = oo->info.string;
2407
    else if (strcmp (oo->name, "maybe_undef") == 0)
2408
      maybe_undef_p = 1;
2409
    else if (strncmp (oo->name, "use_param", 9) == 0
2410
             && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2411
      use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
2412
    else if (strcmp (oo->name, "use_params") == 0)
2413
      use_params_p = 1;
2414
    else if (strcmp (oo->name, "desc") == 0 && oo->kind == OPTION_STRING)
2415
      desc = oo->info.string;
2416
    else if (strcmp (oo->name, "mark_hook") == 0)
2417
      ;
2418
    else if (strcmp (oo->name, "nested_ptr") == 0
2419
             && oo->kind == OPTION_NESTED)
2420
      nested_ptr_d = (const struct nested_ptr_data *) oo->info.nested;
2421
    else if (strcmp (oo->name, "dot") == 0)
2422
      ;
2423
    else if (strcmp (oo->name, "tag") == 0)
2424
      ;
2425
    else if (strcmp (oo->name, "special") == 0)
2426
      ;
2427
    else if (strcmp (oo->name, "skip") == 0)
2428
      ;
2429
    else if (strcmp (oo->name, "atomic") == 0)
2430
      atomic_p = 1;
2431
    else if (strcmp (oo->name, "default") == 0)
2432
      ;
2433
    else if (strcmp (oo->name, "param_is") == 0)
2434
      ;
2435
    else if (strncmp (oo->name, "param", 5) == 0
2436
             && ISDIGIT (oo->name[5]) && strcmp (oo->name + 6, "_is") == 0)
2437
      ;
2438
    else if (strcmp (oo->name, "chain_next") == 0)
2439
      ;
2440
    else if (strcmp (oo->name, "chain_prev") == 0)
2441
      ;
2442
    else if (strcmp (oo->name, "chain_circular") == 0)
2443
      ;
2444
    else if (strcmp (oo->name, "reorder") == 0)
2445
      ;
2446
    else if (strcmp (oo->name, "variable_size") == 0)
2447
      ;
2448
    else
2449
      error_at_line (d->line, "unknown option `%s'\n", oo->name);
2450
 
2451
  if (d->used_length)
2452
    length = NULL;
2453
 
2454
  if (use_params_p)
2455
    {
2456
      int pointer_p = t->kind == TYPE_POINTER;
2457
 
2458
      if (pointer_p)
2459
        t = t->u.p;
2460
      if (!UNION_OR_STRUCT_P (t))
2461
        error_at_line (d->line, "`use_params' option on unimplemented type");
2462
      else
2463
        t = find_param_structure (t, d->param);
2464
      if (pointer_p)
2465
        t = create_pointer (t);
2466
    }
2467
 
2468
  if (use_param_num != -1)
2469
    {
2470
      if (d->param != NULL && d->param[use_param_num] != NULL)
2471
        {
2472
          type_p nt = d->param[use_param_num];
2473
 
2474
          if (t->kind == TYPE_ARRAY)
2475
            nt = create_array (nt, t->u.a.len);
2476
          else if (length != NULL && t->kind == TYPE_POINTER)
2477
            nt = create_pointer (nt);
2478
          d->needs_cast_p = (t->kind != TYPE_POINTER
2479
                             && (nt->kind == TYPE_POINTER
2480
                                 || nt->kind == TYPE_STRING));
2481
          t = nt;
2482
        }
2483
      else
2484
        error_at_line (d->line, "no parameter defined for `%s'", d->val);
2485
    }
2486
 
2487
  if (maybe_undef_p
2488
      && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p)))
2489
    {
2490
      error_at_line (d->line,
2491
                     "field `%s' has invalid option `maybe_undef_p'\n",
2492
                     d->val);
2493
      return;
2494
    }
2495
 
2496
  if (atomic_p && (t->kind != TYPE_POINTER))
2497
    {
2498
      error_at_line (d->line, "field `%s' has invalid option `atomic'\n", d->val);
2499
      return;
2500
    }
2501
 
2502
  switch (t->kind)
2503
    {
2504
    case TYPE_SCALAR:
2505
    case TYPE_STRING:
2506
      d->process_field (t, d);
2507
      break;
2508
 
2509
    case TYPE_POINTER:
2510
      {
2511
        if (maybe_undef_p && t->u.p->u.s.line.file == NULL)
2512
          {
2513
            oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
2514
            break;
2515
          }
2516
 
2517
        /* If a pointer type is marked as "atomic", we process the
2518
           field itself, but we don't walk the data that they point to.
2519
 
2520
           There are two main cases where we walk types: to mark
2521
           pointers that are reachable, and to relocate pointers when
2522
           writing a PCH file.  In both cases, an atomic pointer is
2523
           itself marked or relocated, but the memory that it points
2524
           to is left untouched.  In the case of PCH, that memory will
2525
           be read/written unchanged to the PCH file.  */
2526
        if (atomic_p)
2527
          {
2528
            oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
2529
            d->indent += 2;
2530
            d->process_field (t, d);
2531
            d->indent -= 2;
2532
            oprintf (d->of, "%*s}\n", d->indent, "");
2533
            break;
2534
          }
2535
 
2536
        if (!length)
2537
          {
2538
            if (!UNION_OR_STRUCT_P (t->u.p)
2539
                && t->u.p->kind != TYPE_PARAM_STRUCT)
2540
              {
2541
                error_at_line (d->line,
2542
                               "field `%s' is pointer to unimplemented type",
2543
                               d->val);
2544
                break;
2545
              }
2546
 
2547
            if (nested_ptr_d)
2548
              {
2549
                const char *oldprevval2 = d->prev_val[2];
2550
 
2551
                if (!UNION_OR_STRUCT_P (nested_ptr_d->type))
2552
                  {
2553
                    error_at_line (d->line,
2554
                                   "field `%s' has invalid "
2555
                                   "option `nested_ptr'\n", d->val);
2556
                    return;
2557
                  }
2558
 
2559
                d->prev_val[2] = d->val;
2560
                oprintf (d->of, "%*s{\n", d->indent, "");
2561
                d->indent += 2;
2562
                d->val = xasprintf ("x%d", d->counter++);
2563
                oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
2564
                         (nested_ptr_d->type->kind == TYPE_UNION
2565
                          ? "union" : "struct"),
2566
                         nested_ptr_d->type->u.s.tag,
2567
                         d->fn_wants_lvalue ? "" : "const ", d->val);
2568
                oprintf (d->of, "%*s", d->indent + 2, "");
2569
                output_escaped_param (d, nested_ptr_d->convert_from,
2570
                                      "nested_ptr");
2571
                oprintf (d->of, ";\n");
2572
 
2573
                d->process_field (nested_ptr_d->type, d);
2574
 
2575
                if (d->fn_wants_lvalue)
2576
                  {
2577
                    oprintf (d->of, "%*s%s = ", d->indent, "",
2578
                             d->prev_val[2]);
2579
                    d->prev_val[2] = d->val;
2580
                    output_escaped_param (d, nested_ptr_d->convert_to,
2581
                                          "nested_ptr");
2582
                    oprintf (d->of, ";\n");
2583
                  }
2584
 
2585
                d->indent -= 2;
2586
                oprintf (d->of, "%*s}\n", d->indent, "");
2587
                d->val = d->prev_val[2];
2588
                d->prev_val[2] = oldprevval2;
2589
              }
2590
            else
2591
              d->process_field (t->u.p, d);
2592
          }
2593
        else
2594
          {
2595
            int loopcounter = d->counter++;
2596
            const char *oldval = d->val;
2597
            const char *oldprevval3 = d->prev_val[3];
2598
            char *newval;
2599
 
2600
            oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
2601
            d->indent += 2;
2602
            oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2603
            oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent,
2604
                     "", loopcounter, loopcounter);
2605
            output_escaped_param (d, length, "length");
2606
            oprintf (d->of, "); i%d++) {\n", loopcounter);
2607
            d->indent += 2;
2608
            d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2609
            d->used_length = 1;
2610
            d->prev_val[3] = oldval;
2611
            walk_type (t->u.p, d);
2612
            free (newval);
2613
            d->val = oldval;
2614
            d->prev_val[3] = oldprevval3;
2615
            d->used_length = 0;
2616
            d->indent -= 2;
2617
            oprintf (d->of, "%*s}\n", d->indent, "");
2618
            d->process_field (t, d);
2619
            d->indent -= 2;
2620
            oprintf (d->of, "%*s}\n", d->indent, "");
2621
          }
2622
      }
2623
      break;
2624
 
2625
    case TYPE_ARRAY:
2626
      {
2627
        int loopcounter = d->counter++;
2628
        const char *oldval = d->val;
2629
        char *newval;
2630
 
2631
        /* If it's an array of scalars, we optimize by not generating
2632
           any code.  */
2633
        if (t->u.a.p->kind == TYPE_SCALAR)
2634
          break;
2635
 
2636
        /* When walking an array, compute the length and store it in a
2637
           local variable before walking the array elements, instead of
2638
           recomputing the length expression each time through the loop.
2639
           This is necessary to handle tcc_vl_exp objects like CALL_EXPR,
2640
           where the length is stored in the first array element,
2641
           because otherwise that operand can get overwritten on the
2642
           first iteration.  */
2643
        oprintf (d->of, "%*s{\n", d->indent, "");
2644
        d->indent += 2;
2645
        oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2646
        oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2647
                 d->indent, "", loopcounter);
2648
        if (length)
2649
          output_escaped_param (d, length, "length");
2650
        else
2651
          oprintf (d->of, "%s", t->u.a.len);
2652
        oprintf (d->of, ");\n");
2653
 
2654
        oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
2655
                 d->indent, "",
2656
                 loopcounter, loopcounter, loopcounter, loopcounter);
2657
        d->indent += 2;
2658
        d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2659
        d->used_length = 1;
2660
        walk_type (t->u.a.p, d);
2661
        free (newval);
2662
        d->used_length = 0;
2663
        d->val = oldval;
2664
        d->indent -= 2;
2665
        oprintf (d->of, "%*s}\n", d->indent, "");
2666
        d->indent -= 2;
2667
        oprintf (d->of, "%*s}\n", d->indent, "");
2668
      }
2669
      break;
2670
 
2671
    case TYPE_STRUCT:
2672
    case TYPE_UNION:
2673
      {
2674
        pair_p f;
2675
        const char *oldval = d->val;
2676
        const char *oldprevval1 = d->prev_val[1];
2677
        const char *oldprevval2 = d->prev_val[2];
2678
        const int union_p = t->kind == TYPE_UNION;
2679
        int seen_default_p = 0;
2680
        options_p o;
2681
 
2682
        if (!t->u.s.line.file)
2683
          error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
2684
 
2685
        if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
2686
          {
2687
            error_at_line (d->line,
2688
                           "structure `%s' defined for mismatching languages",
2689
                           t->u.s.tag);
2690
            error_at_line (&t->u.s.line, "one structure defined here");
2691
          }
2692
 
2693
        /* Some things may also be defined in the structure's options.  */
2694
        for (o = t->u.s.opt; o; o = o->next)
2695
          if (!desc && strcmp (o->name, "desc") == 0
2696
              && o->kind == OPTION_STRING)
2697
            desc = o->info.string;
2698
 
2699
        d->prev_val[2] = oldval;
2700
        d->prev_val[1] = oldprevval2;
2701
        if (union_p)
2702
          {
2703
            if (desc == NULL)
2704
              {
2705
                error_at_line (d->line,
2706
                               "missing `desc' option for union `%s'",
2707
                               t->u.s.tag);
2708
                desc = "1";
2709
              }
2710
            oprintf (d->of, "%*sswitch (", d->indent, "");
2711
            output_escaped_param (d, desc, "desc");
2712
            oprintf (d->of, ")\n");
2713
            d->indent += 2;
2714
            oprintf (d->of, "%*s{\n", d->indent, "");
2715
          }
2716
        for (f = t->u.s.fields; f; f = f->next)
2717
          {
2718
            options_p oo;
2719
            const char *dot = ".";
2720
            const char *tagid = NULL;
2721
            int skip_p = 0;
2722
            int default_p = 0;
2723
            int use_param_p = 0;
2724
            char *newval;
2725
 
2726
            d->reorder_fn = NULL;
2727
            for (oo = f->opt; oo; oo = oo->next)
2728
              if (strcmp (oo->name, "dot") == 0
2729
                  && oo->kind == OPTION_STRING)
2730
                dot = oo->info.string;
2731
              else if (strcmp (oo->name, "tag") == 0
2732
                       && oo->kind == OPTION_STRING)
2733
                tagid = oo->info.string;
2734
              else if (strcmp (oo->name, "skip") == 0)
2735
                skip_p = 1;
2736
              else if (strcmp (oo->name, "default") == 0)
2737
                default_p = 1;
2738
              else if (strcmp (oo->name, "reorder") == 0
2739
                  && oo->kind == OPTION_STRING)
2740
                d->reorder_fn = oo->info.string;
2741
              else if (strncmp (oo->name, "use_param", 9) == 0
2742
                       && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2743
                use_param_p = 1;
2744
 
2745
            if (skip_p)
2746
              continue;
2747
 
2748
            if (union_p && tagid)
2749
              {
2750
                oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2751
                d->indent += 2;
2752
              }
2753
            else if (union_p && default_p)
2754
              {
2755
                oprintf (d->of, "%*sdefault:\n", d->indent, "");
2756
                d->indent += 2;
2757
                seen_default_p = 1;
2758
              }
2759
            else if (!union_p && (default_p || tagid))
2760
              error_at_line (d->line,
2761
                             "can't use `%s' outside a union on field `%s'",
2762
                             default_p ? "default" : "tag", f->name);
2763
            else if (union_p && !(default_p || tagid)
2764
                     && f->type->kind == TYPE_SCALAR)
2765
              {
2766
                fprintf (stderr,
2767
                         "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
2768
                         get_input_file_name (d->line->file), d->line->line,
2769
                         f->name);
2770
                continue;
2771
              }
2772
            else if (union_p && !(default_p || tagid))
2773
              error_at_line (d->line,
2774
                             "field `%s' is missing `tag' or `default' option",
2775
                             f->name);
2776
 
2777
            d->line = &f->line;
2778
            d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2779
            d->opt = f->opt;
2780
            d->used_length = false;
2781
 
2782
            if (union_p && use_param_p && d->param == NULL)
2783
              oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
2784
            else
2785
              walk_type (f->type, d);
2786
 
2787
            free (newval);
2788
 
2789
            if (union_p)
2790
              {
2791
                oprintf (d->of, "%*sbreak;\n", d->indent, "");
2792
                d->indent -= 2;
2793
              }
2794
          }
2795
        d->reorder_fn = NULL;
2796
 
2797
        d->val = oldval;
2798
        d->prev_val[1] = oldprevval1;
2799
        d->prev_val[2] = oldprevval2;
2800
 
2801
        if (union_p && !seen_default_p)
2802
          {
2803
            oprintf (d->of, "%*sdefault:\n", d->indent, "");
2804
            oprintf (d->of, "%*s  break;\n", d->indent, "");
2805
          }
2806
        if (union_p)
2807
          {
2808
            oprintf (d->of, "%*s}\n", d->indent, "");
2809
            d->indent -= 2;
2810
          }
2811
      }
2812
      break;
2813
 
2814
    case TYPE_LANG_STRUCT:
2815
      {
2816
        type_p nt;
2817
        for (nt = t->u.s.lang_struct; nt; nt = nt->next)
2818
          if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
2819
            break;
2820
        if (nt == NULL)
2821
          error_at_line (d->line, "structure `%s' differs between languages",
2822
                         t->u.s.tag);
2823
        else
2824
          walk_type (nt, d);
2825
      }
2826
      break;
2827
 
2828
    case TYPE_PARAM_STRUCT:
2829
      {
2830
        type_p *oldparam = d->param;
2831
 
2832
        d->param = t->u.param_struct.param;
2833
        walk_type (t->u.param_struct.stru, d);
2834
        d->param = oldparam;
2835
      }
2836
      break;
2837
 
2838
    default:
2839
      gcc_unreachable ();
2840
    }
2841
}
2842
 
2843
/* process_field routine for marking routines.  */
2844
 
2845
static void
2846
write_types_process_field (type_p f, const struct walk_type_data *d)
2847
{
2848
  const struct write_types_data *wtd;
2849
  const char *cast = d->needs_cast_p ? "(void *)" : "";
2850
  wtd = (const struct write_types_data *) d->cookie;
2851
 
2852
  switch (f->kind)
2853
    {
2854
    case TYPE_NONE:
2855
      gcc_unreachable ();
2856
    case TYPE_POINTER:
2857
      oprintf (d->of, "%*s%s (%s%s", d->indent, "",
2858
               wtd->subfield_marker_routine, cast, d->val);
2859
      if (wtd->param_prefix)
2860
        {
2861
          oprintf (d->of, ", %s", d->prev_val[3]);
2862
          if (d->orig_s)
2863
            {
2864
              oprintf (d->of, ", gt_%s_", wtd->param_prefix);
2865
              output_mangled_typename (d->of, d->orig_s);
2866
            }
2867
          else
2868
            oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
2869
 
2870
          if (f->u.p->kind == TYPE_PARAM_STRUCT
2871
              && f->u.p->u.s.line.file != NULL)
2872
            {
2873
              oprintf (d->of, ", gt_e_");
2874
              output_mangled_typename (d->of, f);
2875
            }
2876
          else if (UNION_OR_STRUCT_P (f) && f->u.p->u.s.line.file != NULL)
2877
            {
2878
              oprintf (d->of, ", gt_ggc_e_");
2879
              output_mangled_typename (d->of, f);
2880
            }
2881
          else
2882
            oprintf (d->of, ", gt_types_enum_last");
2883
        }
2884
      oprintf (d->of, ");\n");
2885
      if (d->reorder_fn && wtd->reorder_note_routine)
2886
        oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
2887
                 wtd->reorder_note_routine, cast, d->val,
2888
                 d->prev_val[3], d->reorder_fn);
2889
      break;
2890
 
2891
    case TYPE_STRING:
2892
    case TYPE_STRUCT:
2893
    case TYPE_UNION:
2894
    case TYPE_LANG_STRUCT:
2895
    case TYPE_PARAM_STRUCT:
2896
      oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
2897
      output_mangled_typename (d->of, f);
2898
      oprintf (d->of, " (%s%s);\n", cast, d->val);
2899
      if (d->reorder_fn && wtd->reorder_note_routine)
2900
        oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
2901
                 wtd->reorder_note_routine, cast, d->val, cast, d->val,
2902
                 d->reorder_fn);
2903
      break;
2904
 
2905
    case TYPE_SCALAR:
2906
      break;
2907
 
2908
    case TYPE_ARRAY:
2909
      gcc_unreachable ();
2910
    }
2911
}
2912
 
2913
/* A subroutine of write_func_for_structure.  Write the enum tag for S.  */
2914
 
2915
static void
2916
output_type_enum (outf_p of, type_p s)
2917
{
2918
  if (s->kind == TYPE_PARAM_STRUCT && s->u.param_struct.line.file != NULL)
2919
    {
2920
      oprintf (of, ", gt_e_");
2921
      output_mangled_typename (of, s);
2922
    }
2923
  else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2924
    {
2925
      oprintf (of, ", gt_ggc_e_");
2926
      output_mangled_typename (of, s);
2927
    }
2928
  else
2929
    oprintf (of, ", gt_types_enum_last");
2930
}
2931
 
2932
/* Return an output file that is suitable for definitions which can
2933
   reference struct S */
2934
 
2935
static outf_p
2936
get_output_file_for_structure (const_type_p s, type_p *param)
2937
{
2938
  const input_file *fn;
2939
  int i;
2940
 
2941
  gcc_assert (UNION_OR_STRUCT_P (s));
2942
  fn = s->u.s.line.file;
2943
 
2944
  /* This is a hack, and not the good kind either.  */
2945
  for (i = NUM_PARAM - 1; i >= 0; i--)
2946
    if (param && param[i] && param[i]->kind == TYPE_POINTER
2947
        && UNION_OR_STRUCT_P (param[i]->u.p))
2948
      fn = param[i]->u.p->u.s.line.file;
2949
 
2950
  /* The call to get_output_file_with_visibility may update fn by
2951
     caching its result inside, so we need the CONST_CAST.  */
2952
  return get_output_file_with_visibility (CONST_CAST (input_file*, fn));
2953
}
2954
 
2955
/* For S, a structure that's part of ORIG_S, and using parameters
2956
   PARAM, write out a routine that:
2957
   - Takes a parameter, a void * but actually of type *S
2958
   - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2959
   field of S or its substructures and (in some cases) things
2960
   that are pointed to by S.
2961
*/
2962
 
2963
static void
2964
write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2965
                          const struct write_types_data *wtd)
2966
{
2967
  const char *chain_next = NULL;
2968
  const char *chain_prev = NULL;
2969
  const char *chain_circular = NULL;
2970
  const char *mark_hook_name = NULL;
2971
  options_p opt;
2972
  struct walk_type_data d;
2973
 
2974
  memset (&d, 0, sizeof (d));
2975
  d.of = get_output_file_for_structure (s, param);
2976
  for (opt = s->u.s.opt; opt; opt = opt->next)
2977
    if (strcmp (opt->name, "chain_next") == 0
2978
        && opt->kind == OPTION_STRING)
2979
      chain_next = opt->info.string;
2980
    else if (strcmp (opt->name, "chain_prev") == 0
2981
             && opt->kind == OPTION_STRING)
2982
      chain_prev = opt->info.string;
2983
    else if (strcmp (opt->name, "chain_circular") == 0
2984
             && opt->kind == OPTION_STRING)
2985
      chain_circular = opt->info.string;
2986
    else if (strcmp (opt->name, "mark_hook") == 0
2987
             && opt->kind == OPTION_STRING)
2988
      mark_hook_name = opt->info.string;
2989
  if (chain_prev != NULL && chain_next == NULL)
2990
    error_at_line (&s->u.s.line, "chain_prev without chain_next");
2991
  if (chain_circular != NULL && chain_next != NULL)
2992
    error_at_line (&s->u.s.line, "chain_circular with chain_next");
2993
  if (chain_circular != NULL)
2994
    chain_next = chain_circular;
2995
 
2996
  d.process_field = write_types_process_field;
2997
  d.cookie = wtd;
2998
  d.orig_s = orig_s;
2999
  d.opt = s->u.s.opt;
3000
  d.line = &s->u.s.line;
3001
  d.bitmap = s->u.s.bitmap;
3002
  d.param = param;
3003
  d.prev_val[0] = "*x";
3004
  d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
3005
  d.prev_val[3] = "x";
3006
  d.val = "(*x)";
3007
 
3008
  oprintf (d.of, "\n");
3009
  oprintf (d.of, "void\n");
3010
  if (param == NULL)
3011
    oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
3012
  else
3013
    {
3014
      oprintf (d.of, "gt_%s_", wtd->prefix);
3015
      output_mangled_typename (d.of, orig_s);
3016
    }
3017
  oprintf (d.of, " (void *x_p)\n");
3018
  oprintf (d.of, "{\n");
3019
  oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
3020
           s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
3021
           chain_next == NULL ? "const " : "",
3022
           s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
3023
  if (chain_next != NULL)
3024
    oprintf (d.of, "  %s %s * xlimit = x;\n",
3025
             s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
3026
  if (chain_next == NULL)
3027
    {
3028
      oprintf (d.of, "  if (%s (x", wtd->marker_routine);
3029
      if (wtd->param_prefix)
3030
        {
3031
          oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
3032
          output_mangled_typename (d.of, orig_s);
3033
          output_type_enum (d.of, orig_s);
3034
        }
3035
      oprintf (d.of, "))\n");
3036
    }
3037
  else
3038
    {
3039
      if (chain_circular != NULL)
3040
        oprintf (d.of, "  if (!%s (xlimit", wtd->marker_routine);
3041
      else
3042
        oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
3043
      if (wtd->param_prefix)
3044
        {
3045
          oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
3046
          output_mangled_typename (d.of, orig_s);
3047
          output_type_enum (d.of, orig_s);
3048
        }
3049
      oprintf (d.of, "))\n");
3050
      if (chain_circular != NULL)
3051
        oprintf (d.of, "    return;\n  do\n");
3052
      if (mark_hook_name && !wtd->skip_hooks)
3053
        {
3054
          oprintf (d.of, "    {\n");
3055
          oprintf (d.of, "      %s (xlimit);\n   ", mark_hook_name);
3056
        }
3057
      oprintf (d.of, "   xlimit = (");
3058
      d.prev_val[2] = "*xlimit";
3059
      output_escaped_param (&d, chain_next, "chain_next");
3060
      oprintf (d.of, ");\n");
3061
      if (mark_hook_name && !wtd->skip_hooks)
3062
        oprintf (d.of, "    }\n");
3063
      if (chain_prev != NULL)
3064
        {
3065
          oprintf (d.of, "  if (x != xlimit)\n");
3066
          oprintf (d.of, "    for (;;)\n");
3067
          oprintf (d.of, "      {\n");
3068
          oprintf (d.of, "        %s %s * const xprev = (",
3069
                   s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
3070
 
3071
          d.prev_val[2] = "*x";
3072
          output_escaped_param (&d, chain_prev, "chain_prev");
3073
          oprintf (d.of, ");\n");
3074
          oprintf (d.of, "        if (xprev == NULL) break;\n");
3075
          oprintf (d.of, "        x = xprev;\n");
3076
          oprintf (d.of, "        (void) %s (xprev", wtd->marker_routine);
3077
          if (wtd->param_prefix)
3078
            {
3079
              oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
3080
              output_mangled_typename (d.of, orig_s);
3081
              output_type_enum (d.of, orig_s);
3082
            }
3083
          oprintf (d.of, ");\n");
3084
          oprintf (d.of, "      }\n");
3085
        }
3086
      if (chain_circular != NULL)
3087
        {
3088
          oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
3089
          if (wtd->param_prefix)
3090
            {
3091
              oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
3092
              output_mangled_typename (d.of, orig_s);
3093
              output_type_enum (d.of, orig_s);
3094
            }
3095
          oprintf (d.of, "));\n");
3096
          if (mark_hook_name && !wtd->skip_hooks)
3097
            oprintf (d.of, "  %s (xlimit);\n", mark_hook_name);
3098
          oprintf (d.of, "  do\n");
3099
        }
3100
      else
3101
        oprintf (d.of, "  while (x != xlimit)\n");
3102
    }
3103
  oprintf (d.of, "    {\n");
3104
  if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
3105
    {
3106
      oprintf (d.of, "      %s (x);\n", mark_hook_name);
3107
    }
3108
  d.prev_val[2] = "*x";
3109
  d.indent = 6;
3110
  walk_type (s, &d);
3111
 
3112
  if (chain_next != NULL)
3113
    {
3114
      oprintf (d.of, "      x = (");
3115
      output_escaped_param (&d, chain_next, "chain_next");
3116
      oprintf (d.of, ");\n");
3117
    }
3118
 
3119
  oprintf (d.of, "    }\n");
3120
  if (chain_circular != NULL)
3121
    oprintf (d.of, "  while (x != xlimit);\n");
3122
  oprintf (d.of, "}\n");
3123
}
3124
 
3125
/* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
3126
 
3127
static void
3128
write_types (outf_p output_header, type_p structures, type_p param_structs,
3129
             const struct write_types_data *wtd)
3130
{
3131
  int nbfun = 0;         /* Count the emitted functions.  */
3132
  type_p s;
3133
 
3134
  oprintf (output_header, "\n/* %s*/\n", wtd->comment);
3135
  /* We first emit the macros and the declarations. Functions' code is
3136
     emitted afterwards.  This is needed in plugin mode.  */
3137
  oprintf (output_header, "/* macros and declarations */\n");
3138
  for (s = structures; s; s = s->next)
3139
    if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
3140
      {
3141
        options_p opt;
3142
 
3143
        if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL)
3144
          continue;
3145
 
3146
        oprintf (output_header, "#define gt_%s_", wtd->prefix);
3147
        output_mangled_typename (output_header, s);
3148
        oprintf (output_header, "(X) do { \\\n");
3149
        oprintf (output_header,
3150
                 "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
3151
                 s->u.s.tag);
3152
        oprintf (output_header, "  } while (0)\n");
3153
 
3154
        for (opt = s->u.s.opt; opt; opt = opt->next)
3155
          if (strcmp (opt->name, "ptr_alias") == 0
3156
              && opt->kind == OPTION_TYPE)
3157
            {
3158
              const_type_p const t = (const_type_p) opt->info.type;
3159
              if (t->kind == TYPE_STRUCT
3160
                  || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
3161
                oprintf (output_header,
3162
                         "#define gt_%sx_%s gt_%sx_%s\n",
3163
                         wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
3164
              else
3165
                error_at_line (&s->u.s.line,
3166
                               "structure alias is not a structure");
3167
              break;
3168
            }
3169
        if (opt)
3170
          continue;
3171
 
3172
        /* Declare the marker procedure only once.  */
3173
        oprintf (output_header,
3174
                 "extern void gt_%sx_%s (void *);\n",
3175
                 wtd->prefix, s->u.s.tag);
3176
 
3177
        if (s->u.s.line.file == NULL)
3178
          {
3179
            fprintf (stderr, "warning: structure `%s' used but not defined\n",
3180
                     s->u.s.tag);
3181
            continue;
3182
          }
3183
      }
3184
 
3185
  for (s = param_structs; s; s = s->next)
3186
    if (s->gc_used == GC_POINTED_TO)
3187
      {
3188
        type_p stru = s->u.param_struct.stru;
3189
 
3190
        /* Declare the marker procedure.  */
3191
        oprintf (output_header, "extern void gt_%s_", wtd->prefix);
3192
        output_mangled_typename (output_header, s);
3193
        oprintf (output_header, " (void *);\n");
3194
 
3195
        if (stru->u.s.line.file == NULL)
3196
          {
3197
            fprintf (stderr, "warning: structure `%s' used but not defined\n",
3198
                     s->u.s.tag);
3199
            continue;
3200
          }
3201
      }
3202
 
3203
  /* At last we emit the functions code.  */
3204
  oprintf (output_header, "\n/* functions code */\n");
3205
  for (s = structures; s; s = s->next)
3206
    if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
3207
      {
3208
        options_p opt;
3209
 
3210
        if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL)
3211
          continue;
3212
        for (opt = s->u.s.opt; opt; opt = opt->next)
3213
          if (strcmp (opt->name, "ptr_alias") == 0)
3214
            break;
3215
        if (opt)
3216
          continue;
3217
 
3218
        if (s->kind == TYPE_LANG_STRUCT)
3219
          {
3220
            type_p ss;
3221
            for (ss = s->u.s.lang_struct; ss; ss = ss->next)
3222
              {
3223
                nbfun++;
3224
                DBGPRINTF ("writing func #%d lang_struct ss @ %p '%s'",
3225
                           nbfun, (void*) ss, ss->u.s.tag);
3226
                write_func_for_structure (s, ss, NULL, wtd);
3227
              }
3228
          }
3229
        else
3230
          {
3231
            nbfun++;
3232
            DBGPRINTF ("writing func #%d struct s @ %p '%s'",
3233
                       nbfun, (void*) s, s->u.s.tag);
3234
            write_func_for_structure (s, s, NULL, wtd);
3235
          }
3236
      }
3237
    else
3238
      {
3239
        /* Structure s is not possibly pointed to, so can be ignored.  */
3240
        DBGPRINTF ("ignored s @ %p  '%s' gc_used#%d",
3241
                   (void*)s,  s->u.s.tag,
3242
                   (int) s->gc_used);
3243
      }
3244
 
3245
  for (s = param_structs; s; s = s->next)
3246
    if (s->gc_used == GC_POINTED_TO)
3247
      {
3248
        type_p *param = s->u.param_struct.param;
3249
        type_p stru = s->u.param_struct.stru;
3250
        if (stru->u.s.line.file == NULL)
3251
          continue;
3252
        if (stru->kind == TYPE_LANG_STRUCT)
3253
          {
3254
            type_p ss;
3255
            for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
3256
              {
3257
                nbfun++;
3258
                DBGPRINTF ("writing func #%d param lang_struct ss @ %p '%s'",
3259
                           nbfun, (void*) ss,  ss->u.s.tag);
3260
                write_func_for_structure (s, ss, param, wtd);
3261
              }
3262
          }
3263
        else
3264
          {
3265
            nbfun++;
3266
            DBGPRINTF ("writing func #%d param struct s @ %p stru @ %p '%s'",
3267
                       nbfun, (void*) s,
3268
                       (void*) stru,  stru->u.s.tag);
3269
            write_func_for_structure (s, stru, param, wtd);
3270
          }
3271
      }
3272
    else
3273
      {
3274
        /* Param structure s is not pointed to, so should be ignored.  */
3275
        DBGPRINTF ("ignored s @ %p", (void*)s);
3276
      }
3277
  if (verbosity_level >= 2)
3278
    printf ("%s emitted %d routines for %s\n",
3279
            progname, nbfun, wtd->comment);
3280
}
3281
 
3282
static const struct write_types_data ggc_wtd = {
3283
  "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
3284
  "GC marker procedures.  ",
3285
  FALSE
3286
};
3287
 
3288
static const struct write_types_data pch_wtd = {
3289
  "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
3290
  "gt_pch_note_reorder",
3291
  "PCH type-walking procedures.  ",
3292
  TRUE
3293
};
3294
 
3295
/* Write out the local pointer-walking routines.  */
3296
 
3297
/* process_field routine for local pointer-walking.  */
3298
 
3299
static void
3300
write_types_local_process_field (type_p f, const struct walk_type_data *d)
3301
{
3302
  switch (f->kind)
3303
    {
3304
    case TYPE_POINTER:
3305
    case TYPE_STRUCT:
3306
    case TYPE_UNION:
3307
    case TYPE_LANG_STRUCT:
3308
    case TYPE_PARAM_STRUCT:
3309
    case TYPE_STRING:
3310
      oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
3311
               d->prev_val[3]);
3312
      oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
3313
      break;
3314
 
3315
    case TYPE_SCALAR:
3316
      break;
3317
 
3318
    default:
3319
      gcc_unreachable ();
3320
    }
3321
}
3322
 
3323
/* For S, a structure that's part of ORIG_S, and using parameters
3324
   PARAM, write out a routine that:
3325
   - Is of type gt_note_pointers
3326
   - Calls PROCESS_FIELD on each field of S or its substructures.
3327
*/
3328
 
3329
static void
3330
write_local_func_for_structure (const_type_p orig_s, type_p s, type_p *param)
3331
{
3332
  struct walk_type_data d;
3333
 
3334
  memset (&d, 0, sizeof (d));
3335
  d.of = get_output_file_for_structure (s, param);
3336
  d.process_field = write_types_local_process_field;
3337
  d.opt = s->u.s.opt;
3338
  d.line = &s->u.s.line;
3339
  d.bitmap = s->u.s.bitmap;
3340
  d.param = param;
3341
  d.prev_val[0] = d.prev_val[2] = "*x";
3342
  d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
3343
  d.prev_val[3] = "x";
3344
  d.val = "(*x)";
3345
  d.fn_wants_lvalue = true;
3346
 
3347
  oprintf (d.of, "\n");
3348
  oprintf (d.of, "void\n");
3349
  oprintf (d.of, "gt_pch_p_");
3350
  output_mangled_typename (d.of, orig_s);
3351
  oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
3352
           "\tvoid *x_p,\n"
3353
           "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3354
           "\tATTRIBUTE_UNUSED void *cookie)\n");
3355
  oprintf (d.of, "{\n");
3356
  oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
3357
           s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
3358
           s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
3359
  d.indent = 2;
3360
  walk_type (s, &d);
3361
  oprintf (d.of, "}\n");
3362
}
3363
 
3364
/* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
3365
 
3366
static void
3367
write_local (outf_p output_header, type_p structures, type_p param_structs)
3368
{
3369
  type_p s;
3370
 
3371
  if (!output_header)
3372
    return;
3373
  oprintf (output_header, "\n/* Local pointer-walking routines.  */\n");
3374
  for (s = structures; s; s = s->next)
3375
    if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
3376
      {
3377
        options_p opt;
3378
 
3379
        if (s->u.s.line.file == NULL)
3380
          continue;
3381
        for (opt = s->u.s.opt; opt; opt = opt->next)
3382
          if (strcmp (opt->name, "ptr_alias") == 0
3383
              && opt->kind == OPTION_TYPE)
3384
            {
3385
              const_type_p const t = (const_type_p) opt->info.type;
3386
              if (t->kind == TYPE_STRUCT
3387
                  || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
3388
                {
3389
                  oprintf (output_header, "#define gt_pch_p_");
3390
                  output_mangled_typename (output_header, s);
3391
                  oprintf (output_header, " gt_pch_p_");
3392
                  output_mangled_typename (output_header, t);
3393
                  oprintf (output_header, "\n");
3394
                }
3395
              else
3396
                error_at_line (&s->u.s.line,
3397
                               "structure alias is not a structure");
3398
              break;
3399
            }
3400
        if (opt)
3401
          continue;
3402
 
3403
        /* Declare the marker procedure only once.  */
3404
        oprintf (output_header, "extern void gt_pch_p_");
3405
        output_mangled_typename (output_header, s);
3406
        oprintf (output_header,
3407
                 "\n    (void *, void *, gt_pointer_operator, void *);\n");
3408
 
3409
        if (s->kind == TYPE_LANG_STRUCT)
3410
          {
3411
            type_p ss;
3412
            for (ss = s->u.s.lang_struct; ss; ss = ss->next)
3413
              write_local_func_for_structure (s, ss, NULL);
3414
          }
3415
        else
3416
          write_local_func_for_structure (s, s, NULL);
3417
      }
3418
 
3419
  for (s = param_structs; s; s = s->next)
3420
    if (s->gc_used == GC_POINTED_TO)
3421
      {
3422
        type_p *param = s->u.param_struct.param;
3423
        type_p stru = s->u.param_struct.stru;
3424
 
3425
        /* Declare the marker procedure.  */
3426
        oprintf (output_header, "extern void gt_pch_p_");
3427
        output_mangled_typename (output_header, s);
3428
        oprintf (output_header,
3429
                 "\n    (void *, void *, gt_pointer_operator, void *);\n");
3430
 
3431
        if (stru->u.s.line.file == NULL)
3432
          {
3433
            fprintf (stderr, "warning: structure `%s' used but not defined\n",
3434
                     s->u.s.tag);
3435
            continue;
3436
          }
3437
 
3438
        if (stru->kind == TYPE_LANG_STRUCT)
3439
          {
3440
            type_p ss;
3441
            for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
3442
              write_local_func_for_structure (s, ss, param);
3443
          }
3444
        else
3445
          write_local_func_for_structure (s, stru, param);
3446
      }
3447
}
3448
 
3449
/* Nonzero if S is a type for which typed GC allocators should be output.  */
3450
 
3451
#define USED_BY_TYPED_GC_P(s)                                           \
3452
  (((s->kind == TYPE_POINTER)                                           \
3453
    && ((s->u.p->gc_used == GC_POINTED_TO)                              \
3454
        || (s->u.p->gc_used == GC_USED)))                               \
3455
   || (UNION_OR_STRUCT_P (s) &&                                         \
3456
       (((s)->gc_used == GC_POINTED_TO)                                 \
3457
        || ((s)->gc_used == GC_MAYBE_POINTED_TO                         \
3458
            && s->u.s.line.file != NULL)                                \
3459
        || ((s)->gc_used == GC_USED                                     \
3460
            && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous"))))))
3461
 
3462
 
3463
/* Write out the 'enum' definition for gt_types_enum.  */
3464
 
3465
static void
3466
write_enum_defn (type_p structures, type_p param_structs)
3467
{
3468
  type_p s;
3469
  int nbstruct = 0;
3470
  int nbparamstruct = 0;
3471
 
3472
  if (!header_file)
3473
    return;
3474
  oprintf (header_file, "\n/* Enumeration of types known.  */\n");
3475
  oprintf (header_file, "enum gt_types_enum {\n");
3476
  for (s = structures; s; s = s->next)
3477
    if (USED_BY_TYPED_GC_P (s))
3478
      {
3479
        nbstruct++;
3480
        DBGPRINTF ("write_enum_defn s @ %p nbstruct %d",
3481
                   (void*) s, nbstruct);
3482
        if (UNION_OR_STRUCT_P (s))
3483
          DBGPRINTF ("write_enum_defn s %p #%d is unionorstruct tagged %s",
3484
                     (void*) s, nbstruct, s->u.s.tag);
3485
        oprintf (header_file, " gt_ggc_e_");
3486
        output_mangled_typename (header_file, s);
3487
        oprintf (header_file, ",\n");
3488
      }
3489
  for (s = param_structs; s; s = s->next)
3490
    if (s->gc_used == GC_POINTED_TO)
3491
      {
3492
        nbparamstruct++;
3493
        DBGPRINTF ("write_enum_defn s %p nbparamstruct %d",
3494
                   (void*) s, nbparamstruct);
3495
        oprintf (header_file, " gt_e_");
3496
        output_mangled_typename (header_file, s);
3497
        oprintf (header_file, ",\n");
3498
      }
3499
  oprintf (header_file, " gt_types_enum_last\n");
3500
  oprintf (header_file, "};\n");
3501
  if (verbosity_level >= 2)
3502
    printf ("%s handled %d GTY-ed structures & %d parameterized structures.\n",
3503
            progname, nbstruct, nbparamstruct);
3504
 
3505
}
3506
 
3507
/* Might T contain any non-pointer elements?  */
3508
 
3509
static int
3510
contains_scalar_p (type_p t)
3511
{
3512
  switch (t->kind)
3513
    {
3514
    case TYPE_STRING:
3515
    case TYPE_POINTER:
3516
      return 0;
3517
    case TYPE_ARRAY:
3518
      return contains_scalar_p (t->u.a.p);
3519
    default:
3520
      /* Could also check for structures that have no non-pointer
3521
         fields, but there aren't enough of those to worry about.  */
3522
      return 1;
3523
    }
3524
}
3525
 
3526
/* Mangle INPF and print it to F.  */
3527
 
3528
static void
3529
put_mangled_filename (outf_p f, const input_file *inpf)
3530
{
3531
  /* The call to get_output_file_name may indirectly update fn since
3532
     get_output_file_with_visibility caches its result inside, so we
3533
     need the CONST_CAST.  */
3534
  const char *name = get_output_file_name (CONST_CAST (input_file*, inpf));
3535
  if (!f || !name)
3536
    return;
3537
  for (; *name != 0; name++)
3538
    if (ISALNUM (*name))
3539
      oprintf (f, "%c", *name);
3540
    else
3541
      oprintf (f, "%c", '_');
3542
}
3543
 
3544
/* Finish off the currently-created root tables in FLP.  PFX, TNAME,
3545
   LASTNAME, and NAME are all strings to insert in various places in
3546
   the resulting code.  */
3547
 
3548
static void
3549
finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
3550
                   const char *tname, const char *name)
3551
{
3552
  struct flist *fli2;
3553
 
3554
  for (fli2 = flp; fli2; fli2 = fli2->next)
3555
    if (fli2->started_p)
3556
      {
3557
        oprintf (fli2->f, "  %s\n", lastname);
3558
        oprintf (fli2->f, "};\n\n");
3559
      }
3560
 
3561
  for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
3562
    if (fli2->started_p)
3563
      {
3564
        lang_bitmap bitmap = get_lang_bitmap (fli2->file);
3565
        int fnum;
3566
 
3567
        for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3568
          if (bitmap & 1)
3569
            {
3570
              oprintf (base_files[fnum],
3571
                       "extern const struct %s gt_%s_", tname, pfx);
3572
              put_mangled_filename (base_files[fnum], fli2->file);
3573
              oprintf (base_files[fnum], "[];\n");
3574
            }
3575
      }
3576
 
3577
  {
3578
    size_t fnum;
3579
    for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
3580
      oprintf (base_files[fnum],
3581
               "EXPORTED_CONST struct %s * const %s[] = {\n", tname, name);
3582
  }
3583
 
3584
 
3585
  for (fli2 = flp; fli2; fli2 = fli2->next)
3586
    if (fli2->started_p)
3587
      {
3588
        lang_bitmap bitmap = get_lang_bitmap (fli2->file);
3589
        int fnum;
3590
 
3591
        fli2->started_p = 0;
3592
 
3593
        for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1)
3594
          if (bitmap & 1)
3595
            {
3596
              oprintf (base_files[fnum], "  gt_%s_", pfx);
3597
              put_mangled_filename (base_files[fnum], fli2->file);
3598
              oprintf (base_files[fnum], ",\n");
3599
            }
3600
      }
3601
 
3602
  {
3603
    size_t fnum;
3604
    for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
3605
      {
3606
        oprintf (base_files[fnum], "  NULL\n");
3607
        oprintf (base_files[fnum], "};\n");
3608
      }
3609
  }
3610
}
3611
 
3612
/* Write the first three fields (pointer, count and stride) for
3613
   root NAME to F.  V and LINE are as for write_root.
3614
 
3615
   Return true if the entry could be written; return false on error.  */
3616
 
3617
static bool
3618
start_root_entry (outf_p f, pair_p v, const char *name, struct fileloc *line)
3619
{
3620
  type_p ap;
3621
 
3622
  if (!v)
3623
    {
3624
      error_at_line (line, "`%s' is too complex to be a root", name);
3625
      return false;
3626
    }
3627
 
3628
  oprintf (f, "  {\n");
3629
  oprintf (f, "    &%s,\n", name);
3630
  oprintf (f, "    1");
3631
 
3632
  for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3633
    if (ap->u.a.len[0])
3634
      oprintf (f, " * (%s)", ap->u.a.len);
3635
    else if (ap == v->type)
3636
      oprintf (f, " * ARRAY_SIZE (%s)", v->name);
3637
  oprintf (f, ",\n");
3638
  oprintf (f, "    sizeof (%s", v->name);
3639
  for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3640
    oprintf (f, "[0]");
3641
  oprintf (f, "),\n");
3642
  return true;
3643
}
3644
 
3645
/* A subroutine of write_root for writing the roots for field FIELD_NAME,
3646
   which has type FIELD_TYPE.  Parameters F to EMIT_PCH are the parameters
3647
   of the caller.  */
3648
 
3649
static void
3650
write_field_root (outf_p f, pair_p v, type_p type, const char *name,
3651
                  int has_length, struct fileloc *line, const char *if_marked,
3652
                  bool emit_pch, type_p field_type, const char *field_name)
3653
{
3654
  struct pair newv;
3655
  /* If the field reference is relative to V, rather than to some
3656
     subcomponent of V, we can mark any subarrays with a single stride.
3657
     We're effectively treating the field as a global variable in its
3658
     own right.  */
3659
  if (v && type == v->type)
3660
    {
3661
      newv = *v;
3662
      newv.type = field_type;
3663
      newv.name = ACONCAT ((v->name, ".", field_name, NULL));
3664
      v = &newv;
3665
    }
3666
  /* Otherwise, any arrays nested in the structure are too complex to
3667
     handle.  */
3668
  else if (field_type->kind == TYPE_ARRAY)
3669
    v = NULL;
3670
  write_root (f, v, field_type, ACONCAT ((name, ".", field_name, NULL)),
3671
              has_length, line, if_marked, emit_pch);
3672
}
3673
 
3674
/* Write out to F the table entry and any marker routines needed to
3675
   mark NAME as TYPE.  V can be one of three values:
3676
 
3677
     - null, if NAME is too complex to represent using a single
3678
       count and stride.  In this case, it is an error for NAME to
3679
       contain any gc-ed data.
3680
 
3681
     - the outermost array that contains NAME, if NAME is part of an array.
3682
 
3683
     - the C variable that contains NAME, if NAME is not part of an array.
3684
 
3685
   LINE is the line of the C source that declares the root variable.
3686
   HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
3687
   is nonzero iff we are building the root table for hash table caches.  */
3688
 
3689
static void
3690
write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
3691
            struct fileloc *line, const char *if_marked, bool emit_pch)
3692
{
3693
  switch (type->kind)
3694
    {
3695
    case TYPE_STRUCT:
3696
      {
3697
        pair_p fld;
3698
        for (fld = type->u.s.fields; fld; fld = fld->next)
3699
          {
3700
            int skip_p = 0;
3701
            const char *desc = NULL;
3702
            options_p o;
3703
 
3704
            for (o = fld->opt; o; o = o->next)
3705
              if (strcmp (o->name, "skip") == 0)
3706
                skip_p = 1;
3707
              else if (strcmp (o->name, "desc") == 0
3708
                       && o->kind == OPTION_STRING)
3709
                desc = o->info.string;
3710
              else if (strcmp (o->name, "param_is") == 0)
3711
                ;
3712
              else
3713
                error_at_line (line,
3714
                               "field `%s' of global `%s' has unknown option `%s'",
3715
                               fld->name, name, o->name);
3716
 
3717
            if (skip_p)
3718
              continue;
3719
            else if (desc && fld->type->kind == TYPE_UNION)
3720
              {
3721
                pair_p validf = NULL;
3722
                pair_p ufld;
3723
 
3724
                for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
3725
                  {
3726
                    const char *tag = NULL;
3727
                    options_p oo;
3728
                    for (oo = ufld->opt; oo; oo = oo->next)
3729
                      if (strcmp (oo->name, "tag") == 0
3730
                          && oo->kind == OPTION_STRING)
3731
                        tag = oo->info.string;
3732
                    if (tag == NULL || strcmp (tag, desc) != 0)
3733
                      continue;
3734
                    if (validf != NULL)
3735
                      error_at_line (line,
3736
                                     "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3737
                                     name, fld->name, validf->name,
3738
                                     name, fld->name, ufld->name, tag);
3739
                    validf = ufld;
3740
                  }
3741
                if (validf != NULL)
3742
                  write_field_root (f, v, type, name, 0, line, if_marked,
3743
                                    emit_pch, validf->type,
3744
                                    ACONCAT ((fld->name, ".",
3745
                                              validf->name, NULL)));
3746
              }
3747
            else if (desc)
3748
              error_at_line (line,
3749
                             "global `%s.%s' has `desc' option but is not union",
3750
                             name, fld->name);
3751
            else
3752
              write_field_root (f, v, type, name, 0, line, if_marked,
3753
                                emit_pch, fld->type, fld->name);
3754
          }
3755
      }
3756
      break;
3757
 
3758
    case TYPE_ARRAY:
3759
      {
3760
        char *newname;
3761
        newname = xasprintf ("%s[0]", name);
3762
        write_root (f, v, type->u.a.p, newname, has_length, line, if_marked,
3763
                    emit_pch);
3764
        free (newname);
3765
      }
3766
      break;
3767
 
3768
    case TYPE_POINTER:
3769
      {
3770
        type_p tp;
3771
 
3772
        if (!start_root_entry (f, v, name, line))
3773
          return;
3774
 
3775
        tp = type->u.p;
3776
 
3777
        if (!has_length && UNION_OR_STRUCT_P (tp))
3778
          {
3779
            oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
3780
            if (emit_pch)
3781
              oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
3782
            else
3783
              oprintf (f, "    NULL");
3784
          }
3785
        else if (!has_length && tp->kind == TYPE_PARAM_STRUCT)
3786
          {
3787
            oprintf (f, "    &gt_ggc_m_");
3788
            output_mangled_typename (f, tp);
3789
            if (emit_pch)
3790
              {
3791
                oprintf (f, ",\n    &gt_pch_n_");
3792
                output_mangled_typename (f, tp);
3793
              }
3794
            else
3795
              oprintf (f, ",\n    NULL");
3796
          }
3797
        else if (has_length
3798
                 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
3799
          {
3800
            oprintf (f, "    &gt_ggc_ma_%s,\n", name);
3801
            if (emit_pch)
3802
              oprintf (f, "    &gt_pch_na_%s", name);
3803
            else
3804
              oprintf (f, "    NULL");
3805
          }
3806
        else
3807
          {
3808
            error_at_line (line,
3809
                           "global `%s' is pointer to unimplemented type",
3810
                           name);
3811
          }
3812
        if (if_marked)
3813
          oprintf (f, ",\n    &%s", if_marked);
3814
        oprintf (f, "\n  },\n");
3815
      }
3816
      break;
3817
 
3818
    case TYPE_STRING:
3819
      {
3820
        if (!start_root_entry (f, v, name, line))
3821
          return;
3822
 
3823
        oprintf (f, "    (gt_pointer_walker) &gt_ggc_m_S,\n");
3824
        oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
3825
        oprintf (f, "  },\n");
3826
      }
3827
      break;
3828
 
3829
    case TYPE_SCALAR:
3830
      break;
3831
 
3832
    default:
3833
      error_at_line (line, "global `%s' is unimplemented type", name);
3834
    }
3835
}
3836
 
3837
/* This generates a routine to walk an array.  */
3838
 
3839
static void
3840
write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
3841
{
3842
  struct walk_type_data d;
3843
  char *prevval3;
3844
 
3845
  memset (&d, 0, sizeof (d));
3846
  d.of = f;
3847
  d.cookie = wtd;
3848
  d.indent = 2;
3849
  d.line = &v->line;
3850
  d.opt = v->opt;
3851
  d.bitmap = get_lang_bitmap (v->line.file);
3852
  d.param = NULL;
3853
 
3854
  d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3855
 
3856
  if (wtd->param_prefix)
3857
    {
3858
      oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3859
      oprintf (f, "    (void *, void *, gt_pointer_operator, void *);\n");
3860
      oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
3861
               wtd->param_prefix, v->name);
3862
      oprintf (d.of,
3863
               "      ATTRIBUTE_UNUSED void *x_p,\n"
3864
               "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3865
               "      ATTRIBUTE_UNUSED void * cookie)\n");
3866
      oprintf (d.of, "{\n");
3867
      d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3868
      d.process_field = write_types_local_process_field;
3869
      walk_type (v->type, &d);
3870
      oprintf (f, "}\n\n");
3871
    }
3872
 
3873
  d.opt = v->opt;
3874
  oprintf (f, "static void gt_%sa_%s (void *);\n", wtd->prefix, v->name);
3875
  oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
3876
           wtd->prefix, v->name);
3877
  oprintf (f, "{\n");
3878
  d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3879
  d.process_field = write_types_process_field;
3880
  walk_type (v->type, &d);
3881
  free (prevval3);
3882
  oprintf (f, "}\n\n");
3883
}
3884
 
3885
/* Output a table describing the locations and types of VARIABLES.  */
3886
 
3887
static void
3888
write_roots (pair_p variables, bool emit_pch)
3889
{
3890
  pair_p v;
3891
  struct flist *flp = NULL;
3892
 
3893
  for (v = variables; v; v = v->next)
3894
    {
3895
      outf_p f =
3896
        get_output_file_with_visibility (CONST_CAST (input_file*,
3897
                                                     v->line.file));
3898
      struct flist *fli;
3899
      const char *length = NULL;
3900
      int deletable_p = 0;
3901
      options_p o;
3902
      for (o = v->opt; o; o = o->next)
3903
        if (strcmp (o->name, "length") == 0
3904
            && o->kind == OPTION_STRING)
3905
          length = o->info.string;
3906
        else if (strcmp (o->name, "deletable") == 0)
3907
          deletable_p = 1;
3908
        else if (strcmp (o->name, "param_is") == 0)
3909
          ;
3910
        else if (strncmp (o->name, "param", 5) == 0
3911
                 && ISDIGIT (o->name[5]) && strcmp (o->name + 6, "_is") == 0)
3912
          ;
3913
        else if (strcmp (o->name, "if_marked") == 0)
3914
          ;
3915
        else
3916
          error_at_line (&v->line,
3917
                         "global `%s' has unknown option `%s'",
3918
                         v->name, o->name);
3919
 
3920
      for (fli = flp; fli; fli = fli->next)
3921
        if (fli->f == f && f)
3922
          break;
3923
      if (fli == NULL)
3924
        {
3925
          fli = XNEW (struct flist);
3926
          fli->f = f;
3927
          fli->next = flp;
3928
          fli->started_p = 0;
3929
          fli->file = v->line.file;
3930
          gcc_assert (fli->file);
3931
          flp = fli;
3932
 
3933
          oprintf (f, "\n/* GC roots.  */\n\n");
3934
        }
3935
 
3936
      if (!deletable_p
3937
          && length
3938
          && v->type->kind == TYPE_POINTER
3939
          && (v->type->u.p->kind == TYPE_POINTER
3940
              || v->type->u.p->kind == TYPE_STRUCT))
3941
        {
3942
          write_array (f, v, &ggc_wtd);
3943
          write_array (f, v, &pch_wtd);
3944
        }
3945
    }
3946
 
3947
  for (v = variables; v; v = v->next)
3948
    {
3949
      outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*,
3950
                                                              v->line.file));
3951
      struct flist *fli;
3952
      int skip_p = 0;
3953
      int length_p = 0;
3954
      options_p o;
3955
 
3956
      for (o = v->opt; o; o = o->next)
3957
        if (strcmp (o->name, "length") == 0)
3958
          length_p = 1;
3959
        else if (strcmp (o->name, "deletable") == 0
3960
                 || strcmp (o->name, "if_marked") == 0)
3961
          skip_p = 1;
3962
 
3963
      if (skip_p)
3964
        continue;
3965
 
3966
      for (fli = flp; fli; fli = fli->next)
3967
        if (fli->f == f)
3968
          break;
3969
      if (!fli->started_p)
3970
        {
3971
          fli->started_p = 1;
3972
 
3973
          oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_");
3974
          put_mangled_filename (f, v->line.file);
3975
          oprintf (f, "[] = {\n");
3976
        }
3977
 
3978
      write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
3979
    }
3980
 
3981
  finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3982
                     "gt_ggc_rtab");
3983
 
3984
  for (v = variables; v; v = v->next)
3985
    {
3986
      outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*,
3987
                                                              v->line.file));
3988
      struct flist *fli;
3989
      int skip_p = 1;
3990
      options_p o;
3991
 
3992
      for (o = v->opt; o; o = o->next)
3993
        if (strcmp (o->name, "deletable") == 0)
3994
          skip_p = 0;
3995
        else if (strcmp (o->name, "if_marked") == 0)
3996
          skip_p = 1;
3997
 
3998
      if (skip_p)
3999
        continue;
4000
 
4001
      for (fli = flp; fli; fli = fli->next)
4002
        if (fli->f == f)
4003
          break;
4004
      if (!fli->started_p)
4005
        {
4006
          fli->started_p = 1;
4007
 
4008
          oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_");
4009
          put_mangled_filename (f, v->line.file);
4010
          oprintf (f, "[] = {\n");
4011
        }
4012
 
4013
      oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
4014
               v->name, v->name);
4015
    }
4016
 
4017
  finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
4018
                     "gt_ggc_deletable_rtab");
4019
 
4020
  for (v = variables; v; v = v->next)
4021
    {
4022
      outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*,
4023
                                                              v->line.file));
4024
      struct flist *fli;
4025
      const char *if_marked = NULL;
4026
      int length_p = 0;
4027
      options_p o;
4028
 
4029
      for (o = v->opt; o; o = o->next)
4030
        if (strcmp (o->name, "length") == 0)
4031
          length_p = 1;
4032
        else if (strcmp (o->name, "if_marked") == 0
4033
                       && o->kind == OPTION_STRING)
4034
          if_marked = o->info.string;
4035
       if (if_marked == NULL)
4036
        continue;
4037
      if (v->type->kind != TYPE_POINTER
4038
          || v->type->u.p->kind != TYPE_PARAM_STRUCT
4039
          || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
4040
        {
4041
          error_at_line (&v->line,
4042
                         "if_marked option used but not hash table");
4043
          continue;
4044
        }
4045
 
4046
      for (fli = flp; fli; fli = fli->next)
4047
        if (fli->f == f)
4048
          break;
4049
      if (!fli->started_p)
4050
        {
4051
          fli->started_p = 1;
4052
 
4053
          oprintf (f, "EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc_");
4054
          put_mangled_filename (f, v->line.file);
4055
          oprintf (f, "[] = {\n");
4056
        }
4057
 
4058
      write_root (f, v, v->type->u.p->u.param_struct.param[0],
4059
                  v->name, length_p, &v->line, if_marked, emit_pch);
4060
    }
4061
 
4062
  finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
4063
                     "gt_ggc_cache_rtab");
4064
 
4065
  if (!emit_pch)
4066
    return;
4067
 
4068
  for (v = variables; v; v = v->next)
4069
    {
4070
      outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*,
4071
                                                              v->line.file));
4072
      struct flist *fli;
4073
      int length_p = 0;
4074
      int if_marked_p = 0;
4075
      options_p o;
4076
 
4077
      for (o = v->opt; o; o = o->next)
4078
        if (strcmp (o->name, "length") == 0)
4079
          length_p = 1;
4080
        else if (strcmp (o->name, "if_marked") == 0)
4081
          if_marked_p = 1;
4082
 
4083
      if (!if_marked_p)
4084
        continue;
4085
 
4086
      for (fli = flp; fli; fli = fli->next)
4087
        if (fli->f == f)
4088
          break;
4089
      if (!fli->started_p)
4090
        {
4091
          fli->started_p = 1;
4092
 
4093
          oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rc_");
4094
          put_mangled_filename (f, v->line.file);
4095
          oprintf (f, "[] = {\n");
4096
        }
4097
 
4098
      write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
4099
    }
4100
 
4101
  finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
4102
                     "gt_pch_cache_rtab");
4103
 
4104
  for (v = variables; v; v = v->next)
4105
    {
4106
      outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*,
4107
                                                              v->line.file));
4108
      struct flist *fli;
4109
      int skip_p = 0;
4110
      options_p o;
4111
 
4112
      for (o = v->opt; o; o = o->next)
4113
        if (strcmp (o->name, "deletable") == 0
4114
            || strcmp (o->name, "if_marked") == 0)
4115
          skip_p = 1;
4116
 
4117
      if (skip_p)
4118
        continue;
4119
 
4120
      if (!contains_scalar_p (v->type))
4121
        continue;
4122
 
4123
      for (fli = flp; fli; fli = fli->next)
4124
        if (fli->f == f)
4125
          break;
4126
      if (!fli->started_p)
4127
        {
4128
          fli->started_p = 1;
4129
 
4130
          oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_");
4131
          put_mangled_filename (f, v->line.file);
4132
          oprintf (f, "[] = {\n");
4133
        }
4134
 
4135
      oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
4136
               v->name, v->name);
4137
    }
4138
 
4139
  finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
4140
                     "gt_pch_scalar_rtab");
4141
}
4142
/* Record the definition of the vec_prefix structure, as defined in vec.h:
4143
 
4144
   struct vec_prefix GTY(()) {
4145
   unsigned num;
4146
   unsigned alloc;
4147
   };  */
4148
static type_p
4149
vec_prefix_type (void)
4150
{
4151
  static type_p prefix_type = NULL;
4152
  if (prefix_type == NULL)
4153
    {
4154
      pair_p fields;
4155
      static struct fileloc pos = { NULL, 0 };
4156
      type_p len_ty = create_scalar_type ("unsigned");
4157
      pos.file = input_file_by_name (__FILE__); pos.line = __LINE__;
4158
      fields = create_field_at (0, len_ty, "alloc", 0, &pos);
4159
      fields = create_field_at (fields, len_ty, "num", 0, &pos);
4160
      prefix_type = new_structure ("vec_prefix", 0, &pos, fields, 0);
4161
      prefix_type->u.s.bitmap = -1;
4162
    }
4163
  return prefix_type;
4164
}
4165
 
4166
/* Record the definition of a generic VEC structure, as if we had expanded
4167
   the macros in vec.h:
4168
 
4169
   typedef struct VEC_<type>_base GTY(()) {
4170
   struct vec_prefix prefix;
4171
   <type> GTY((length ("%h.prefix.num"))) vec[1];
4172
   } VEC_<type>_base
4173
 
4174
   where the GTY(()) tags are only present if is_scalar is _false_.  */
4175
 
4176
void
4177
note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
4178
{
4179
  pair_p fields;
4180
  type_p t;
4181
  options_p o;
4182
  const char *name = concat ("VEC_", type_name, "_base", (char *) 0);
4183
 
4184
  if (is_scalar)
4185
    {
4186
      t = create_scalar_type (type_name);
4187
      o = 0;
4188
    }
4189
  else
4190
    {
4191
      t = resolve_typedef (type_name, pos);
4192
      o = create_string_option (0, "length", "%h.prefix.num");
4193
    }
4194
  /* We assemble the field list in reverse order.  */
4195
  fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
4196
  fields = create_field_at (fields, vec_prefix_type (), "prefix", 0, pos);
4197
 
4198
  do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
4199
}
4200
 
4201
/* Record the definition of an allocation-specific VEC structure, as if
4202
   we had expanded the macros in vec.h:
4203
 
4204
   typedef struct VEC_<type>_<astrat> {
4205
     VEC_<type>_base base;
4206
   } VEC_<type>_<astrat>;
4207
*/
4208
void
4209
note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
4210
{
4211
  const char *astratname = concat ("VEC_", type, "_", astrat, (char *) 0);
4212
  const char *basename = concat ("VEC_", type, "_base", (char *) 0);
4213
 
4214
  pair_p field = create_field_at (0, resolve_typedef (basename, pos),
4215
                                  "base", 0, pos);
4216
 
4217
  do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
4218
}
4219
 
4220
/* Returns the specifier keyword for a string or union type S, empty string
4221
   otherwise.  */
4222
 
4223
static const char *
4224
get_type_specifier (const type_p s)
4225
{
4226
  if (s->kind == TYPE_STRUCT || s->kind == TYPE_LANG_STRUCT)
4227
    return "struct ";
4228
  if (s->kind == TYPE_UNION)
4229
    return "union ";
4230
  return "";
4231
}
4232
 
4233
/* TRUE if type S has the GTY variable_size annotation.  */
4234
 
4235
static bool
4236
variable_size_p (const type_p s)
4237
{
4238
  options_p o;
4239
  for (o = s->u.s.opt; o; o = o->next)
4240
    if (strcmp (o->name, "variable_size") == 0)
4241
      return true;
4242
  return false;
4243
}
4244
 
4245
enum alloc_quantity
4246
{ single, vector };
4247
enum alloc_zone
4248
{ any_zone, specific_zone };
4249
 
4250
/* Writes one typed allocator definition into output F for type
4251
   identifier TYPE_NAME with optional type specifier TYPE_SPECIFIER.
4252
   The allocator name will contain ALLOCATOR_TYPE.  If VARIABLE_SIZE
4253
   is true, the allocator will have an extra parameter specifying
4254
   number of bytes to allocate.  If QUANTITY is set to VECTOR, a
4255
   vector allocator will be output, if ZONE is set to SPECIFIC_ZONE,
4256
   the allocator will be zone-specific.  */
4257
 
4258
static void
4259
write_typed_alloc_def (outf_p f,
4260
                       bool variable_size, const char *type_specifier,
4261
                       const char *type_name, const char *allocator_type,
4262
                       enum alloc_quantity quantity, enum alloc_zone zone)
4263
{
4264
  bool two_args = variable_size && (quantity == vector);
4265
  bool third_arg = ((zone == specific_zone)
4266
                    && (variable_size || (quantity == vector)));
4267
  gcc_assert (f != NULL);
4268
  oprintf (f, "#define ggc_alloc_%s%s", allocator_type, type_name);
4269
  oprintf (f, "(%s%s%s%s%s) ",
4270
           (variable_size ? "SIZE" : ""),
4271
           (two_args ? ", " : ""),
4272
           (quantity == vector) ? "n" : "",
4273
           (third_arg ? ", " : ""), (zone == specific_zone) ? "z" : "");
4274
  oprintf (f, "((%s%s *)", type_specifier, type_name);
4275
  oprintf (f, "(ggc_internal_%salloc_stat (", allocator_type);
4276
  if (zone == specific_zone)
4277
    oprintf (f, "z, ");
4278
  if (variable_size)
4279
    oprintf (f, "SIZE");
4280
  else
4281
    oprintf (f, "sizeof (%s%s)", type_specifier, type_name);
4282
  if (quantity == vector)
4283
    oprintf (f, ", n");
4284
  oprintf (f, " MEM_STAT_INFO)))\n");
4285
}
4286
 
4287
/* Writes a typed allocator definition into output F for a struct or
4288
   union S, with a given ALLOCATOR_TYPE and QUANTITY for ZONE.  */
4289
 
4290
static void
4291
write_typed_struct_alloc_def (outf_p f,
4292
                              const type_p s, const char *allocator_type,
4293
                              enum alloc_quantity quantity,
4294
                              enum alloc_zone zone)
4295
{
4296
  gcc_assert (UNION_OR_STRUCT_P (s));
4297
  write_typed_alloc_def (f, variable_size_p (s), get_type_specifier (s),
4298
                         s->u.s.tag, allocator_type, quantity, zone);
4299
}
4300
 
4301
/* Writes a typed allocator definition into output F for a typedef P,
4302
   with a given ALLOCATOR_TYPE and QUANTITY for ZONE.  */
4303
 
4304
static void
4305
write_typed_typedef_alloc_def (outf_p f,
4306
                               const pair_p p, const char *allocator_type,
4307
                               enum alloc_quantity quantity,
4308
                               enum alloc_zone zone)
4309
{
4310
  write_typed_alloc_def (f, variable_size_p (p->type), "", p->name,
4311
                         allocator_type, quantity, zone);
4312
}
4313
 
4314
/* Writes typed allocator definitions into output F for the types in
4315
   STRUCTURES and TYPEDEFS that are used by GC.  */
4316
 
4317
static void
4318
write_typed_alloc_defns (outf_p f,
4319
                         const type_p structures, const pair_p typedefs)
4320
{
4321
  type_p s;
4322
  pair_p p;
4323
 
4324
  gcc_assert (f != NULL);
4325
  oprintf (f,
4326
           "\n/* Allocators for known structs and unions.  */\n\n");
4327
  for (s = structures; s; s = s->next)
4328
    {
4329
      if (!USED_BY_TYPED_GC_P (s))
4330
        continue;
4331
      gcc_assert (UNION_OR_STRUCT_P (s));
4332
      /* In plugin mode onput output ggc_alloc macro definitions
4333
         relevant to plugin input files.  */
4334
      if (nb_plugin_files > 0
4335
          && ((s->u.s.line.file == NULL) || !s->u.s.line.file->inpisplugin))
4336
        continue;
4337
      write_typed_struct_alloc_def (f, s, "", single, any_zone);
4338
      write_typed_struct_alloc_def (f, s, "cleared_", single, any_zone);
4339
      write_typed_struct_alloc_def (f, s, "vec_", vector, any_zone);
4340
      write_typed_struct_alloc_def (f, s, "cleared_vec_", vector, any_zone);
4341
      write_typed_struct_alloc_def (f, s, "zone_", single, specific_zone);
4342
      write_typed_struct_alloc_def (f, s, "zone_cleared_", single,
4343
                                    specific_zone);
4344
      write_typed_struct_alloc_def (f, s, "zone_vec_", vector, specific_zone);
4345
      write_typed_struct_alloc_def (f, s, "zone_cleared_vec_", vector,
4346
                                    specific_zone);
4347
    }
4348
 
4349
  oprintf (f, "\n/* Allocators for known typedefs.  */\n");
4350
  for (p = typedefs; p; p = p->next)
4351
    {
4352
      s = p->type;
4353
      if (!USED_BY_TYPED_GC_P (s) || (strcmp (p->name, s->u.s.tag) == 0))
4354
        continue;
4355
      /* In plugin mode onput output ggc_alloc macro definitions
4356
         relevant to plugin input files.  */
4357
      if (nb_plugin_files > 0)
4358
        {
4359
          struct fileloc* filoc = type_fileloc(s);
4360
          if (!filoc || !filoc->file->inpisplugin)
4361
            continue;
4362
        };
4363
      write_typed_typedef_alloc_def (f, p, "", single, any_zone);
4364
      write_typed_typedef_alloc_def (f, p, "cleared_", single, any_zone);
4365
      write_typed_typedef_alloc_def (f, p, "vec_", vector, any_zone);
4366
      write_typed_typedef_alloc_def (f, p, "cleared_vec_", vector, any_zone);
4367
      write_typed_typedef_alloc_def (f, p, "zone_", single, specific_zone);
4368
      write_typed_typedef_alloc_def (f, p, "zone_cleared_", single,
4369
                                     specific_zone);
4370
      write_typed_typedef_alloc_def (f, p, "zone_cleared_vec_", vector,
4371
                                     specific_zone);
4372
    }
4373
}
4374
 
4375
/* Prints not-as-ugly version of a typename of T to OF.  Trades the uniquness
4376
   guaranteee for somewhat increased readability.  If name conflicts do happen,
4377
   this funcion will have to be adjusted to be more like
4378
   output_mangled_typename.  */
4379
 
4380
static void
4381
output_typename (outf_p of, const_type_p t)
4382
{
4383
  switch (t->kind)
4384
    {
4385
    case TYPE_STRING:
4386
      oprintf (of, "str");
4387
      break;
4388
    case TYPE_SCALAR:
4389
      oprintf (of, "scalar");
4390
      break;
4391
    case TYPE_POINTER:
4392
      output_typename (of, t->u.p);
4393
      break;
4394
    case TYPE_STRUCT:
4395
    case TYPE_UNION:
4396
    case TYPE_LANG_STRUCT:
4397
      oprintf (of, "%s", t->u.s.tag);
4398
      break;
4399
    case TYPE_PARAM_STRUCT:
4400
      {
4401
        int i;
4402
        for (i = 0; i < NUM_PARAM; i++)
4403
          if (t->u.param_struct.param[i] != NULL)
4404
            {
4405
              output_typename (of, t->u.param_struct.param[i]);
4406
              oprintf (of, "_");
4407
            }
4408
        output_typename (of, t->u.param_struct.stru);
4409
        break;
4410
      }
4411
    default:
4412
      gcc_unreachable ();
4413
    }
4414
}
4415
 
4416
/* Writes a typed GC allocator for type S that is suitable as a callback for
4417
   the splay tree implementation in libiberty.  */
4418
 
4419
static void
4420
write_splay_tree_allocator_def (const_type_p s)
4421
{
4422
  outf_p of = get_output_file_with_visibility (NULL);
4423
  oprintf (of, "void * ggc_alloc_splay_tree_");
4424
  output_typename (of, s);
4425
  oprintf (of, " (int sz, void * nl)\n");
4426
  oprintf (of, "{\n");
4427
  oprintf (of, "  return ggc_splay_alloc (");
4428
  oprintf (of, "gt_e_");
4429
  output_mangled_typename (of, s);
4430
  oprintf (of, ", sz, nl);\n");
4431
  oprintf (of, "}\n\n");
4432
}
4433
 
4434
/* Writes typed GC allocators for PARAM_STRUCTS that are suitable as callbacks
4435
   for the splay tree implementation in libiberty.  */
4436
 
4437
static void
4438
write_splay_tree_allocators (const_type_p param_structs)
4439
{
4440
  const_type_p s;
4441
 
4442
  oprintf (header_file, "\n/* Splay tree callback allocators.  */\n");
4443
  for (s = param_structs; s; s = s->next)
4444
    if (s->gc_used == GC_POINTED_TO)
4445
      {
4446
        oprintf (header_file, "extern void * ggc_alloc_splay_tree_");
4447
        output_typename (header_file, s);
4448
        oprintf (header_file, " (int, void *);\n");
4449
        write_splay_tree_allocator_def (s);
4450
      }
4451
}
4452
 
4453
static void dump_pair (int indent, pair_p p);
4454
static void dump_type (int indent, type_p p);
4455
static void dump_type_list (int indent, type_p p);
4456
 
4457
#define INDENT 2
4458
 
4459
/* Dumps the value of typekind KIND.  */
4460
 
4461
static void
4462
dump_typekind (int indent, enum typekind kind)
4463
{
4464
  printf ("%*ckind = ", indent, ' ');
4465
  switch (kind)
4466
    {
4467
    case TYPE_SCALAR:
4468
      printf ("TYPE_SCALAR");
4469
      break;
4470
    case TYPE_STRING:
4471
      printf ("TYPE_STRING");
4472
      break;
4473
    case TYPE_STRUCT:
4474
      printf ("TYPE_STRUCT");
4475
      break;
4476
    case TYPE_UNION:
4477
      printf ("TYPE_UNION");
4478
      break;
4479
    case TYPE_POINTER:
4480
      printf ("TYPE_POINTER");
4481
      break;
4482
    case TYPE_ARRAY:
4483
      printf ("TYPE_ARRAY");
4484
      break;
4485
    case TYPE_LANG_STRUCT:
4486
      printf ("TYPE_LANG_STRUCT");
4487
      break;
4488
    case TYPE_PARAM_STRUCT:
4489
      printf ("TYPE_PARAM_STRUCT");
4490
      break;
4491
    default:
4492
      gcc_unreachable ();
4493
    }
4494
  printf ("\n");
4495
}
4496
 
4497
/* Dumps the value of GC_USED flag.  */
4498
 
4499
static void
4500
dump_gc_used (int indent, enum gc_used_enum gc_used)
4501
{
4502
  printf ("%*cgc_used = ", indent, ' ');
4503
  switch (gc_used)
4504
    {
4505
    case GC_UNUSED:
4506
      printf ("GC_UNUSED");
4507
      break;
4508
    case GC_USED:
4509
      printf ("GC_USED");
4510
      break;
4511
    case GC_MAYBE_POINTED_TO:
4512
      printf ("GC_MAYBE_POINTED_TO");
4513
      break;
4514
    case GC_POINTED_TO:
4515
      printf ("GC_POINTED_TO");
4516
      break;
4517
    default:
4518
      gcc_unreachable ();
4519
    }
4520
  printf ("\n");
4521
}
4522
 
4523
/* Dumps the type options OPT.  */
4524
 
4525
static void
4526
dump_options (int indent, options_p opt)
4527
{
4528
  options_p o;
4529
  printf ("%*coptions = ", indent, ' ');
4530
  o = opt;
4531
  while (o)
4532
    {
4533
      switch (o->kind)
4534
        {
4535
        case OPTION_STRING:
4536
          printf ("%s:string %s ", o->name, o->info.string);
4537
          break;
4538
        case OPTION_TYPE:
4539
          printf ("%s:type ", o->name);
4540
          dump_type (indent+1, o->info.type);
4541
          break;
4542
        case OPTION_NESTED:
4543
          printf ("%s:nested ", o->name);
4544
          break;
4545
        case OPTION_NONE:
4546
          gcc_unreachable ();
4547
        }
4548
      o = o->next;
4549
    }
4550
  printf ("\n");
4551
}
4552
 
4553
/* Dumps the source file location in LINE.  */
4554
 
4555
static void
4556
dump_fileloc (int indent, struct fileloc line)
4557
{
4558
  printf ("%*cfileloc: file = %s, line = %d\n", indent, ' ',
4559
          get_input_file_name (line.file),
4560
          line.line);
4561
}
4562
 
4563
/* Recursively dumps the struct, union, or a language-specific
4564
   struct T.  */
4565
 
4566
static void
4567
dump_type_u_s (int indent, type_p t)
4568
{
4569
  pair_p fields;
4570
 
4571
  gcc_assert (t->kind == TYPE_STRUCT || t->kind == TYPE_UNION
4572
              || t->kind == TYPE_LANG_STRUCT);
4573
  printf ("%*cu.s.tag = %s\n", indent, ' ', t->u.s.tag);
4574
  dump_fileloc (indent, t->u.s.line);
4575
  printf ("%*cu.s.fields =\n", indent, ' ');
4576
  fields = t->u.s.fields;
4577
  while (fields)
4578
    {
4579
      dump_pair (indent + INDENT, fields);
4580
      fields = fields->next;
4581
    }
4582
  printf ("%*cend of fields of type %p\n", indent, ' ', (void *) t);
4583
  dump_options (indent, t->u.s.opt);
4584
  printf ("%*cu.s.bitmap = %X\n", indent, ' ', t->u.s.bitmap);
4585
  if (t->kind == TYPE_LANG_STRUCT)
4586
    {
4587
      printf ("%*cu.s.lang_struct:\n", indent, ' ');
4588
      dump_type_list (indent + INDENT, t->u.s.lang_struct);
4589
    }
4590
}
4591
 
4592
/* Recursively dumps the array T.  */
4593
 
4594
static void
4595
dump_type_u_a (int indent, type_p t)
4596
{
4597
  gcc_assert (t->kind == TYPE_ARRAY);
4598
  printf ("%*clen = %s, u.a.p:\n", indent, ' ', t->u.a.len);
4599
  dump_type_list (indent + INDENT, t->u.a.p);
4600
}
4601
 
4602
/* Recursively dumps the parameterized struct T.  */
4603
 
4604
static void
4605
dump_type_u_param_struct (int indent, type_p t)
4606
{
4607
  int i;
4608
  gcc_assert (t->kind == TYPE_PARAM_STRUCT);
4609
  printf ("%*cu.param_struct.stru:\n", indent, ' ');
4610
  dump_type_list (indent, t->u.param_struct.stru);
4611
  dump_fileloc (indent, t->u.param_struct.line);
4612
  for (i = 0; i < NUM_PARAM; i++)
4613
    {
4614
      if (t->u.param_struct.param[i] == NULL)
4615
        continue;
4616
      printf ("%*cu.param_struct.param[%d]:\n", indent, ' ', i);
4617
      dump_type (indent + INDENT, t->u.param_struct.param[i]);
4618
    }
4619
}
4620
 
4621
/* Recursively dumps the type list T.  */
4622
 
4623
static void
4624
dump_type_list (int indent, type_p t)
4625
{
4626
  type_p p = t;
4627
  while (p)
4628
    {
4629
      dump_type (indent, p);
4630
      p = p->next;
4631
    }
4632
}
4633
 
4634
static htab_t seen_types;
4635
 
4636
/* Recursively dumps the type T if it was not dumped previously.  */
4637
 
4638
static void
4639
dump_type (int indent, type_p t)
4640
{
4641
  PTR *slot;
4642
 
4643
  printf ("%*cType at %p: ", indent, ' ', (void *) t);
4644
  slot = htab_find_slot (seen_types, t, INSERT);
4645
  if (*slot != NULL)
4646
    {
4647
      printf ("already seen.\n");
4648
      return;
4649
    }
4650
  *slot = t;
4651
  printf ("\n");
4652
 
4653
  dump_typekind (indent, t->kind);
4654
  printf ("%*cpointer_to = %p\n", indent + INDENT, ' ',
4655
          (void *) t->pointer_to);
4656
  dump_gc_used (indent + INDENT, t->gc_used);
4657
  switch (t->kind)
4658
    {
4659
    case TYPE_SCALAR:
4660
      printf ("%*cscalar_is_char = %s\n", indent + INDENT, ' ',
4661
              t->u.scalar_is_char ? "true" : "false");
4662
      break;
4663
    case TYPE_STRING:
4664
      break;
4665
    case TYPE_STRUCT:
4666
    case TYPE_UNION:
4667
    case TYPE_LANG_STRUCT:
4668
      dump_type_u_s (indent + INDENT, t);
4669
      break;
4670
    case TYPE_POINTER:
4671
      printf ("%*cp:\n", indent + INDENT, ' ');
4672
      dump_type (indent + INDENT, t->u.p);
4673
      break;
4674
    case TYPE_ARRAY:
4675
      dump_type_u_a (indent + INDENT, t);
4676
      break;
4677
    case TYPE_PARAM_STRUCT:
4678
      dump_type_u_param_struct (indent + INDENT, t);
4679
      break;
4680
    default:
4681
      gcc_unreachable ();
4682
    }
4683
  printf ("%*cEnd of type at %p\n", indent, ' ', (void *) t);
4684
}
4685
 
4686
/* Dumps the pair P.  */
4687
 
4688
static void
4689
dump_pair (int indent, pair_p p)
4690
{
4691
  printf ("%*cpair: name = %s\n", indent, ' ', p->name);
4692
  dump_type (indent, p->type);
4693
  dump_fileloc (indent, p->line);
4694
  dump_options (indent, p->opt);
4695
  printf ("%*cEnd of pair %s\n", indent, ' ', p->name);
4696
}
4697
 
4698
/* Dumps the list of pairs PP.  */
4699
 
4700
static void
4701
dump_pair_list (const char *name, pair_p pp)
4702
{
4703
  pair_p p;
4704
  printf ("%s:\n", name);
4705
  for (p = pp; p != NULL; p = p->next)
4706
    dump_pair (0, p);
4707
  printf ("End of %s\n\n", name);
4708
}
4709
 
4710
/* Dumps the STRUCTURES.  */
4711
 
4712
static void
4713
dump_structures (const char *name, type_p structures)
4714
{
4715
  printf ("%s:\n", name);
4716
  dump_type_list (0, structures);
4717
  printf ("End of %s\n\n", name);
4718
}
4719
 
4720
/* Dumps the internal structures of gengtype.  This is useful to debug
4721
   gengtype itself, or to understand what it does, e.g. for plugin
4722
   developers.  */
4723
 
4724
static void
4725
dump_everything (void)
4726
{
4727
  seen_types = htab_create (100, htab_hash_pointer, htab_eq_pointer, NULL);
4728
  dump_pair_list ("typedefs", typedefs);
4729
  dump_structures ("structures", structures);
4730
  dump_structures ("param_structs", param_structs);
4731
  dump_pair_list ("variables", variables);
4732
  htab_delete (seen_types);
4733
}
4734
 
4735
 
4736
 
4737
/* Option specification for getopt_long.  */
4738
static const struct option gengtype_long_options[] = {
4739
  {"help", no_argument, NULL, 'h'},
4740
  {"version", no_argument, NULL, 'V'},
4741
  {"verbose", no_argument, NULL, 'v'},
4742
  {"dump", no_argument, NULL, 'd'},
4743
  {"debug", no_argument, NULL, 'D'},
4744
  {"plugin", required_argument, NULL, 'P'},
4745
  {"srcdir", required_argument, NULL, 'S'},
4746
  {"backupdir", required_argument, NULL, 'B'},
4747
  {"inputs", required_argument, NULL, 'I'},
4748
  {"read-state", required_argument, NULL, 'r'},
4749
  {"write-state", required_argument, NULL, 'w'},
4750
  /* Terminating NULL placeholder.  */
4751
  {NULL, no_argument, NULL, 0},
4752
};
4753
 
4754
 
4755
static void
4756
print_usage (void)
4757
{
4758
  printf ("Usage: %s\n", progname);
4759
  printf ("\t -h | --help " " \t# Give this help.\n");
4760
  printf ("\t -D | --debug "
4761
          " \t# Give debug output to debug %s itself.\n", progname);
4762
  printf ("\t -V | --version " " \t# Give version information.\n");
4763
  printf ("\t -v | --verbose  \t# Increase verbosity.  Can be given several times.\n");
4764
  printf ("\t -d | --dump " " \t# Dump state for debugging.\n");
4765
  printf ("\t -P | --plugin <output-file> <plugin-src> ... "
4766
          " \t# Generate for plugin.\n");
4767
  printf ("\t -S | --srcdir <GCC-directory> "
4768
          " \t# Specify the GCC source directory.\n");
4769
  printf ("\t -B | --backupdir <directory> "
4770
          " \t# Specify the backup directory for updated files.\n");
4771
  printf ("\t -I | --inputs <input-list> "
4772
          " \t# Specify the file with source files list.\n");
4773
  printf ("\t -w | --write-state <state-file> " " \t# Write a state file.\n");
4774
  printf ("\t -r | --read-state <state-file> " " \t# Read a state file.\n");
4775
}
4776
 
4777
static void
4778
print_version (void)
4779
{
4780
  printf ("%s %s%s\n", progname, pkgversion_string, version_string);
4781
  printf ("Report bugs: %s\n", bug_report_url);
4782
}
4783
 
4784
/* Parse the program options using getopt_long... */
4785
static void
4786
parse_program_options (int argc, char **argv)
4787
{
4788
  int opt = -1;
4789
  while ((opt = getopt_long (argc, argv, "hVvdP:S:B:I:w:r:D",
4790
                             gengtype_long_options, NULL)) >= 0)
4791
    {
4792
      switch (opt)
4793
        {
4794
        case 'h':               /* --help */
4795
          print_usage ();
4796
          break;
4797
        case 'V':               /* --version */
4798
          print_version ();
4799
          break;
4800
        case 'd':               /* --dump */
4801
          do_dump = 1;
4802
          break;
4803
        case 'D':               /* --debug */
4804
          do_debug = 1;
4805
          break;
4806
        case 'v':               /* --verbose */
4807
          verbosity_level++;
4808
          break;
4809
        case 'P':               /* --plugin */
4810
          if (optarg)
4811
            plugin_output_filename = optarg;
4812
          else
4813
            fatal ("missing plugin output file name");
4814
          break;
4815
        case 'S':               /* --srcdir */
4816
          if (optarg)
4817
            srcdir = optarg;
4818
          else
4819
            fatal ("missing source directory");
4820
          srcdir_len = strlen (srcdir);
4821
          break;
4822
        case 'B':               /* --backupdir */
4823
          if (optarg)
4824
            backup_dir = optarg;
4825
          else
4826
            fatal ("missing backup directory");
4827
          break;
4828
        case 'I':               /* --inputs */
4829
          if (optarg)
4830
            inputlist = optarg;
4831
          else
4832
            fatal ("missing input list");
4833
          break;
4834
        case 'r':               /* --read-state */
4835
          if (optarg)
4836
            read_state_filename = optarg;
4837
          else
4838
            fatal ("missing read state file");
4839
          DBGPRINTF ("read state %s\n", optarg);
4840
          break;
4841
        case 'w':               /* --write-state */
4842
          DBGPRINTF ("write state %s\n", optarg);
4843
          if (optarg)
4844
            write_state_filename = optarg;
4845
          else
4846
            fatal ("missing write state file");
4847
          break;
4848
        default:
4849
          fprintf (stderr, "%s: unknown flag '%c'\n", progname, opt);
4850
          print_usage ();
4851
          fatal ("unexpected flag");
4852
        }
4853
    };
4854
  if (plugin_output_filename)
4855
    {
4856
      /* In plugin mode we require some input files.  */
4857
      int i = 0;
4858
      if (optind >= argc)
4859
        fatal ("no source files given in plugin mode");
4860
      nb_plugin_files = argc - optind;
4861
      plugin_files = XNEWVEC (input_file*, nb_plugin_files);
4862
      for (i = 0; i < (int) nb_plugin_files; i++)
4863
        {
4864
          char *name = argv[i + optind];
4865
          plugin_files[i] = input_file_by_name (name);
4866
        }
4867
    }
4868
}
4869
 
4870
 
4871
 
4872
/******* Manage input files.  ******/
4873
 
4874
/* Hash table of unique input file names.  */
4875
static htab_t input_file_htab;
4876
 
4877
/* Find or allocate a new input_file by hash-consing it.  */
4878
input_file*
4879
input_file_by_name (const char* name)
4880
{
4881
  PTR* slot;
4882
  input_file* f = NULL;
4883
  int namlen = 0;
4884
  if (!name)
4885
    return NULL;
4886
  namlen = strlen (name);
4887
  f = XCNEWVAR (input_file, sizeof (input_file)+namlen+2);
4888
  f->inpbitmap = 0;
4889
  f->inpoutf = NULL;
4890
  f->inpisplugin = false;
4891
  strcpy (f->inpname, name);
4892
  slot = htab_find_slot (input_file_htab, f, INSERT);
4893
  gcc_assert (slot != NULL);
4894
  if (*slot)
4895
    {
4896
      /* Already known input file.  */
4897
      free (f);
4898
      return (input_file*)(*slot);
4899
    }
4900
  /* New input file.  */
4901
  *slot = f;
4902
  return f;
4903
    }
4904
 
4905
/* Hash table support routines for input_file-s.  */
4906
static hashval_t
4907
htab_hash_inputfile (const void *p)
4908
{
4909
  const input_file *inpf = (const input_file *) p;
4910
  gcc_assert (inpf);
4911
  return htab_hash_string (get_input_file_name (inpf));
4912
}
4913
 
4914
static int
4915
htab_eq_inputfile (const void *x, const void *y)
4916
{
4917
  const input_file *inpfx = (const input_file *) x;
4918
  const input_file *inpfy = (const input_file *) y;
4919
  gcc_assert (inpfx != NULL && inpfy != NULL);
4920
  return !filename_cmp (get_input_file_name (inpfx), get_input_file_name (inpfy));
4921
}
4922
 
4923
 
4924
int
4925
main (int argc, char **argv)
4926
{
4927
  size_t i;
4928
  static struct fileloc pos = { NULL, 0 };
4929
  outf_p output_header;
4930
 
4931
  /* Mandatory common initializations.  */
4932
  progname = "gengtype";        /* For fatal and messages.  */
4933
  /* Create the hash-table used to hash-cons input files.  */
4934
  input_file_htab =
4935
    htab_create (800, htab_hash_inputfile, htab_eq_inputfile, NULL);
4936
  /* Initialize our special input files.  */
4937
  this_file = input_file_by_name (__FILE__);
4938
  system_h_file = input_file_by_name ("system.h");
4939
  /* Set the scalar_is_char union number for predefined scalar types.  */
4940
  scalar_nonchar.u.scalar_is_char = FALSE;
4941
  scalar_char.u.scalar_is_char = TRUE;
4942
 
4943
  parse_program_options (argc, argv);
4944
 
4945
#if ENABLE_CHECKING
4946
  if (do_debug)
4947
    {
4948
      time_t now = (time_t) 0;
4949
      time (&now);
4950
      DBGPRINTF ("gengtype started pid %d at %s",
4951
                 (int) getpid (), ctime (&now));
4952
    }
4953
#endif  /* ENABLE_CHECKING */
4954
 
4955
  /* Parse the input list and the input files.  */
4956
  DBGPRINTF ("inputlist %s", inputlist);
4957
  if (read_state_filename)
4958
    {
4959
      if (inputlist)
4960
        fatal ("input list %s cannot be given with a read state file %s",
4961
               inputlist, read_state_filename);
4962
      read_state (read_state_filename);
4963
      DBGPRINT_COUNT_TYPE ("structures after read_state", structures);
4964
      DBGPRINT_COUNT_TYPE ("param_structs after read_state", param_structs);
4965
    }
4966
  else if (inputlist)
4967
    {
4968
      /* These types are set up with #define or else outside of where
4969
         we can see them.  We should initialize them before calling
4970
         read_input_list.  */
4971
#define POS_HERE(Call) do { pos.file = this_file; pos.line = __LINE__; \
4972
        Call;} while(0)
4973
      POS_HERE (do_scalar_typedef ("CUMULATIVE_ARGS", &pos));
4974
      POS_HERE (do_scalar_typedef ("REAL_VALUE_TYPE", &pos));
4975
      POS_HERE (do_scalar_typedef ("FIXED_VALUE_TYPE", &pos));
4976
      POS_HERE (do_scalar_typedef ("double_int", &pos));
4977
      POS_HERE (do_scalar_typedef ("uint64_t", &pos));
4978
      POS_HERE (do_scalar_typedef ("uint8", &pos));
4979
      POS_HERE (do_scalar_typedef ("jword", &pos));
4980
      POS_HERE (do_scalar_typedef ("JCF_u2", &pos));
4981
      POS_HERE (do_scalar_typedef ("void", &pos));
4982
      POS_HERE (do_typedef ("PTR",
4983
                            create_pointer (resolve_typedef ("void", &pos)),
4984
                            &pos));
4985
#undef POS_HERE
4986
      read_input_list (inputlist);
4987
      for (i = 0; i < num_gt_files; i++)
4988
        {
4989
          parse_file (get_input_file_name (gt_files[i]));
4990
          DBGPRINTF ("parsed file #%d %s",
4991
                     (int) i, get_input_file_name (gt_files[i]));
4992
        }
4993
      if (verbosity_level >= 1)
4994
        printf ("%s parsed %d files with %d GTY types\n",
4995
                progname, (int) num_gt_files, type_count);
4996
 
4997
      DBGPRINT_COUNT_TYPE ("structures after parsing", structures);
4998
      DBGPRINT_COUNT_TYPE ("param_structs after parsing", param_structs);
4999
 
5000
    }
5001
  else
5002
    fatal ("either an input list or a read state file should be given");
5003
  if (hit_error)
5004
    return 1;
5005
 
5006
 
5007
  if (plugin_output_filename)
5008
    {
5009
      size_t ix = 0;
5010
      /* In plugin mode, we should have read a state file, and have
5011
         given at least one plugin file.  */
5012
      if (!read_state_filename)
5013
        fatal ("No read state given in plugin mode for %s",
5014
               plugin_output_filename);
5015
 
5016
      if (nb_plugin_files == 0 || !plugin_files)
5017
        fatal ("No plugin files given in plugin mode for %s",
5018
               plugin_output_filename);
5019
 
5020
      /* Parse our plugin files and augment the state.  */
5021
      for (ix = 0; ix < nb_plugin_files; ix++)
5022
        {
5023
          input_file* pluginput = plugin_files [ix];
5024
          pluginput->inpisplugin = true;
5025
          parse_file (get_input_file_name (pluginput));
5026
        }
5027
      if (hit_error)
5028
        return 1;
5029
 
5030
      plugin_output = create_file ("GCC", plugin_output_filename);
5031
      DBGPRINTF ("created plugin_output %p named %s",
5032
                 (void *) plugin_output, plugin_output->name);
5033
    }
5034
  else
5035
    {                           /* No plugin files, we are in normal mode.  */
5036
      if (!srcdir)
5037
        fatal ("gengtype needs a source directory in normal mode");
5038
    }
5039
  if (hit_error)
5040
    return 1;
5041
 
5042
  gen_rtx_next ();
5043
 
5044
  /* The call to set_gc_used may indirectly call find_param_structure
5045
     hence enlarge the param_structs list of types.  */
5046
  set_gc_used (variables);
5047
 
5048
 /* The state at this point is read from the state input file or by
5049
    parsing source files and optionally augmented by parsing plugin
5050
    source files.  Write it now.  */
5051
  if (write_state_filename)
5052
    {
5053
      DBGPRINT_COUNT_TYPE ("structures before write_state", structures);
5054
      DBGPRINT_COUNT_TYPE ("param_structs before write_state", param_structs);
5055
 
5056
      if (hit_error)
5057
        fatal ("didn't write state file %s after errors",
5058
               write_state_filename);
5059
 
5060
      DBGPRINTF ("before write_state %s", write_state_filename);
5061
      write_state (write_state_filename);
5062
 
5063
      if (do_dump)
5064
        dump_everything ();
5065
 
5066
      /* After having written the state file we return immediately to
5067
         avoid generating any output file.  */
5068
      if (hit_error)
5069
        return 1;
5070
      else
5071
        return 0;
5072
    }
5073
 
5074
 
5075
  open_base_files ();
5076
 
5077
  write_enum_defn (structures, param_structs);
5078
  output_header = plugin_output ? plugin_output : header_file;
5079
  write_typed_alloc_defns (output_header, structures, typedefs);
5080
  DBGPRINT_COUNT_TYPE ("structures before write_types outputheader",
5081
                       structures);
5082
  DBGPRINT_COUNT_TYPE ("param_structs before write_types outputheader",
5083
                       param_structs);
5084
 
5085
  write_types (output_header, structures, param_structs, &ggc_wtd);
5086
  if (plugin_files == NULL)
5087
    {
5088
      DBGPRINT_COUNT_TYPE ("structures before write_types headerfil",
5089
                           structures);
5090
      DBGPRINT_COUNT_TYPE ("param_structs before write_types headerfil",
5091
                           param_structs);
5092
      write_types (header_file, structures, param_structs, &pch_wtd);
5093
      write_local (header_file, structures, param_structs);
5094
    }
5095
  write_splay_tree_allocators (param_structs);
5096
  write_roots (variables, plugin_files == NULL);
5097
  write_rtx_next ();
5098
  close_output_files ();
5099
 
5100
  if (do_dump)
5101
    dump_everything ();
5102
 
5103
  /* Don't bother about free-ing any input or plugin file, etc.  */
5104
 
5105
  if (hit_error)
5106
    return 1;
5107
  return 0;
5108
}

powered by: WebSVN 2.1.0

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