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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of gcc/gengtype.cc