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