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