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