gengtype.c revision 169689
1/* Process source files and output type information.
2   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 2, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING.  If not, write to the Free
18Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
1902110-1301, USA.  */
20
21#include "bconfig.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "gengtype.h"
26#include "gtyp-gen.h"
27#include "errors.h"
28
29/* Nonzero iff an error has occurred.  */
30static int hit_error = 0;
31
32static void gen_rtx_next (void);
33static void write_rtx_next (void);
34static void open_base_files (void);
35static void close_output_files (void);
36
37/* Report an error at POS, printing MSG.  */
38
39void
40error_at_line (struct fileloc *pos, const char *msg, ...)
41{
42  va_list ap;
43
44  va_start (ap, msg);
45
46  fprintf (stderr, "%s:%d: ", pos->file, pos->line);
47  vfprintf (stderr, msg, ap);
48  fputc ('\n', stderr);
49  hit_error = 1;
50
51  va_end (ap);
52}
53
54/* vasprintf, but produces fatal message on out-of-memory.  */
55int
56xvasprintf (char **result, const char *format, va_list args)
57{
58  int ret = vasprintf (result, format, args);
59  if (*result == NULL || ret < 0)
60    {
61      fputs ("gengtype: out of memory", stderr);
62      xexit (1);
63    }
64  return ret;
65}
66
67/* Wrapper for xvasprintf.  */
68char *
69xasprintf (const char *format, ...)
70{
71  char *result;
72  va_list ap;
73
74  va_start (ap, format);
75  xvasprintf (&result, format, ap);
76  va_end (ap);
77  return result;
78}
79
80/* The one and only TYPE_STRING.  */
81
82struct type string_type = {
83  TYPE_STRING, NULL, NULL, GC_USED, {0}
84};
85
86/* Lists of various things.  */
87
88static pair_p typedefs;
89static type_p structures;
90static type_p param_structs;
91static pair_p variables;
92
93static void do_scalar_typedef (const char *, struct fileloc *);
94static type_p find_param_structure
95  (type_p t, type_p param[NUM_PARAM]);
96static type_p adjust_field_tree_exp (type_p t, options_p opt);
97static type_p adjust_field_rtx_def (type_p t, options_p opt);
98
99/* Define S as a typedef to T at POS.  */
100
101void
102do_typedef (const char *s, type_p t, struct fileloc *pos)
103{
104  pair_p p;
105
106  for (p = typedefs; p != NULL; p = p->next)
107    if (strcmp (p->name, s) == 0)
108      {
109	if (p->type != t)
110	  {
111	    error_at_line (pos, "type `%s' previously defined", s);
112	    error_at_line (&p->line, "previously defined here");
113	  }
114	return;
115      }
116
117  p = XNEW (struct pair);
118  p->next = typedefs;
119  p->name = s;
120  p->type = t;
121  p->line = *pos;
122  typedefs = p;
123}
124
125/* Define S as a typename of a scalar.  */
126
127static void
128do_scalar_typedef (const char *s, struct fileloc *pos)
129{
130  do_typedef (s, create_scalar_type (s, strlen (s)), pos);
131}
132
133/* Return the type previously defined for S.  Use POS to report errors.  */
134
135type_p
136resolve_typedef (const char *s, struct fileloc *pos)
137{
138  pair_p p;
139  for (p = typedefs; p != NULL; p = p->next)
140    if (strcmp (p->name, s) == 0)
141      return p->type;
142  error_at_line (pos, "unidentified type `%s'", s);
143  return create_scalar_type ("char", 4);
144}
145
146/* Create and return a new structure with tag NAME (or a union iff
147   ISUNION is nonzero), at POS with fields FIELDS and options O.  */
148
149type_p
150new_structure (const char *name, int isunion, struct fileloc *pos,
151	       pair_p fields, options_p o)
152{
153  type_p si;
154  type_p s = NULL;
155  lang_bitmap bitmap = get_base_file_bitmap (pos->file);
156
157  for (si = structures; si != NULL; si = si->next)
158    if (strcmp (name, si->u.s.tag) == 0
159	&& UNION_P (si) == isunion)
160      {
161	type_p ls = NULL;
162	if (si->kind == TYPE_LANG_STRUCT)
163	  {
164	    ls = si;
165
166	    for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
167	      if (si->u.s.bitmap == bitmap)
168		s = si;
169	  }
170	else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
171	  {
172	    ls = si;
173	    si = XCNEW (struct type);
174	    memcpy (si, ls, sizeof (struct type));
175	    ls->kind = TYPE_LANG_STRUCT;
176	    ls->u.s.lang_struct = si;
177	    ls->u.s.fields = NULL;
178	    si->next = NULL;
179	    si->pointer_to = NULL;
180	    si->u.s.lang_struct = ls;
181	  }
182	else
183	  s = si;
184
185	if (ls != NULL && s == NULL)
186	  {
187	    s = XCNEW (struct type);
188	    s->next = ls->u.s.lang_struct;
189	    ls->u.s.lang_struct = s;
190	    s->u.s.lang_struct = ls;
191	  }
192	break;
193      }
194
195  if (s == NULL)
196    {
197      s = XCNEW (struct type);
198      s->next = structures;
199      structures = s;
200    }
201
202  if (s->u.s.line.file != NULL
203      || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
204    {
205      error_at_line (pos, "duplicate structure definition");
206      error_at_line (&s->u.s.line, "previous definition here");
207    }
208
209  s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
210  s->u.s.tag = name;
211  s->u.s.line = *pos;
212  s->u.s.fields = fields;
213  s->u.s.opt = o;
214  s->u.s.bitmap = bitmap;
215  if (s->u.s.lang_struct)
216    s->u.s.lang_struct->u.s.bitmap |= bitmap;
217
218  return s;
219}
220
221/* Return the previously-defined structure with tag NAME (or a union
222   iff ISUNION is nonzero), or a new empty structure or union if none
223   was defined previously.  */
224
225type_p
226find_structure (const char *name, int isunion)
227{
228  type_p s;
229
230  for (s = structures; s != NULL; s = s->next)
231    if (strcmp (name, s->u.s.tag) == 0
232	&& UNION_P (s) == isunion)
233      return s;
234
235  s = XCNEW (struct type);
236  s->next = structures;
237  structures = s;
238  s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
239  s->u.s.tag = name;
240  structures = s;
241  return s;
242}
243
244/* Return the previously-defined parameterized structure for structure
245   T and parameters PARAM, or a new parameterized empty structure or
246   union if none was defined previously.  */
247
248static type_p
249find_param_structure (type_p t, type_p param[NUM_PARAM])
250{
251  type_p res;
252
253  for (res = param_structs; res; res = res->next)
254    if (res->u.param_struct.stru == t
255	&& memcmp (res->u.param_struct.param, param,
256		   sizeof (type_p) * NUM_PARAM) == 0)
257      break;
258  if (res == NULL)
259    {
260      res = XCNEW (struct type);
261      res->kind = TYPE_PARAM_STRUCT;
262      res->next = param_structs;
263      param_structs = res;
264      res->u.param_struct.stru = t;
265      memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
266    }
267  return res;
268}
269
270/* Return a scalar type with name NAME.  */
271
272type_p
273create_scalar_type (const char *name, size_t name_len)
274{
275  type_p r = XCNEW (struct type);
276  r->kind = TYPE_SCALAR;
277  r->u.sc = (char *) xmemdup (name, name_len, name_len + 1);
278  return r;
279}
280
281/* Return a pointer to T.  */
282
283type_p
284create_pointer (type_p t)
285{
286  if (! t->pointer_to)
287    {
288      type_p r = XCNEW (struct type);
289      r->kind = TYPE_POINTER;
290      r->u.p = t;
291      t->pointer_to = r;
292    }
293  return t->pointer_to;
294}
295
296/* Return an array of length LEN.  */
297
298type_p
299create_array (type_p t, const char *len)
300{
301  type_p v;
302
303  v = XCNEW (struct type);
304  v->kind = TYPE_ARRAY;
305  v->u.a.p = t;
306  v->u.a.len = len;
307  return v;
308}
309
310/* Return an options structure with name NAME and info INFO.  NEXT is the
311   next option in the chain.  */
312
313options_p
314create_option (options_p next, const char *name, const void *info)
315{
316  options_p o = XNEW (struct options);
317  o->next = next;
318  o->name = name;
319  o->info = (const char*) info;
320  return o;
321}
322
323/* Add a variable named S of type T with options O defined at POS,
324   to `variables'.  */
325
326void
327note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
328{
329  pair_p n;
330  n = XNEW (struct pair);
331  n->name = s;
332  n->type = t;
333  n->line = *pos;
334  n->opt = o;
335  n->next = variables;
336  variables = n;
337}
338
339/* Create a fake field with the given type and name.  NEXT is the next
340   field in the chain.  */
341
342static pair_p
343create_field (pair_p next, type_p type, const char *name)
344{
345  pair_p field;
346
347  field = XNEW (struct pair);
348  field->next = next;
349  field->type = type;
350  field->name = name;
351  field->opt = NULL;
352  field->line.file = __FILE__;
353  field->line.line = __LINE__;
354  return field;
355}
356
357/* Like create_field, but the field is only valid when condition COND
358   is true.  */
359
360static pair_p
361create_optional_field (pair_p next, type_p type, const char *name,
362		       const char *cond)
363{
364  static int id = 1;
365  pair_p union_fields, field;
366  type_p union_type;
367
368  /* Create a fake union type with a single nameless field of type TYPE.
369     The field has a tag of "1".  This allows us to make the presence
370     of a field of type TYPE depend on some boolean "desc" being true.  */
371  union_fields = create_field (NULL, type, "");
372  union_fields->opt = create_option (union_fields->opt, "dot", "");
373  union_fields->opt = create_option (union_fields->opt, "tag", "1");
374  union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
375			      &lexer_line, union_fields, NULL);
376
377  /* Create the field and give it the new fake union type.  Add a "desc"
378     tag that specifies the condition under which the field is valid.  */
379  field = create_field (next, union_type, name);
380  field->opt = create_option (field->opt, "desc", cond);
381  return field;
382}
383
384/* We don't care how long a CONST_DOUBLE is.  */
385#define CONST_DOUBLE_FORMAT "ww"
386/* We don't want to see codes that are only for generator files.  */
387#undef GENERATOR_FILE
388
389enum rtx_code {
390#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
391#include "rtl.def"
392#undef DEF_RTL_EXPR
393  NUM_RTX_CODE
394};
395
396static const char * const rtx_name[NUM_RTX_CODE] = {
397#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
398#include "rtl.def"
399#undef DEF_RTL_EXPR
400};
401
402static const char * const rtx_format[NUM_RTX_CODE] = {
403#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
404#include "rtl.def"
405#undef DEF_RTL_EXPR
406};
407
408static int rtx_next_new[NUM_RTX_CODE];
409
410/* We also need codes and names for insn notes (not register notes).
411   Note that we do *not* bias the note values here.  */
412enum insn_note {
413#define DEF_INSN_NOTE(NAME) NAME,
414#include "insn-notes.def"
415#undef DEF_INSN_NOTE
416
417  NOTE_INSN_MAX
418};
419
420/* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
421   default field for line number notes.  */
422static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
423#define DEF_INSN_NOTE(NAME) #NAME,
424#include "insn-notes.def"
425#undef DEF_INSN_NOTE
426};
427
428#undef CONST_DOUBLE_FORMAT
429#define GENERATOR_FILE
430
431/* Generate the contents of the rtx_next array.  This really doesn't belong
432   in gengtype at all, but it's needed for adjust_field_rtx_def.  */
433
434static void
435gen_rtx_next (void)
436{
437  int i;
438  for (i = 0; i < NUM_RTX_CODE; i++)
439    {
440      int k;
441
442      rtx_next_new[i] = -1;
443      if (strncmp (rtx_format[i], "iuu", 3) == 0)
444	rtx_next_new[i] = 2;
445      else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
446	rtx_next_new[i] = 1;
447      else
448	for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
449	  if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
450	    rtx_next_new[i] = k;
451    }
452}
453
454/* Write out the contents of the rtx_next array.  */
455static void
456write_rtx_next (void)
457{
458  outf_p f = get_output_file_with_visibility (NULL);
459  int i;
460
461  oprintf (f, "\n/* Used to implement the RTX_NEXT macro.  */\n");
462  oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
463  for (i = 0; i < NUM_RTX_CODE; i++)
464    if (rtx_next_new[i] == -1)
465      oprintf (f, "  0,\n");
466    else
467      oprintf (f,
468	       "  RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
469	       rtx_next_new[i]);
470  oprintf (f, "};\n");
471}
472
473/* Handle `special("rtx_def")'.  This is a special case for field
474   `fld' of struct rtx_def, which is an array of unions whose values
475   are based in a complex way on the type of RTL.  */
476
477static type_p
478adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
479{
480  pair_p flds = NULL;
481  options_p nodot;
482  int i;
483  type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
484  type_p bitmap_tp, basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
485
486  if (t->kind != TYPE_UNION)
487    {
488      error_at_line (&lexer_line,
489		     "special `rtx_def' must be applied to a union");
490      return &string_type;
491    }
492
493  nodot = create_option (NULL, "dot", "");
494
495  rtx_tp = create_pointer (find_structure ("rtx_def", 0));
496  rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
497  tree_tp = create_pointer (find_structure ("tree_node", 1));
498  mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
499  reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
500  bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
501  basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
502  constant_tp = create_pointer (find_structure ("constant_descriptor_rtx", 0));
503  scalar_tp = create_scalar_type ("rtunion scalar", 14);
504
505  {
506    pair_p note_flds = NULL;
507    int c;
508
509    for (c = 0; c <= NOTE_INSN_MAX; c++)
510      {
511	switch (c)
512	  {
513	  case NOTE_INSN_MAX:
514	    note_flds = create_field (note_flds, &string_type, "rt_str");
515	    break;
516
517	  case NOTE_INSN_BLOCK_BEG:
518	  case NOTE_INSN_BLOCK_END:
519	    note_flds = create_field (note_flds, tree_tp, "rt_tree");
520	    break;
521
522	  case NOTE_INSN_EXPECTED_VALUE:
523	  case NOTE_INSN_VAR_LOCATION:
524	    note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
525	    break;
526
527	  default:
528	    note_flds = create_field (note_flds, scalar_tp, "rt_int");
529	    break;
530	  }
531	/* NOTE_INSN_MAX is used as the default field for line
532	   number notes.  */
533	if (c == NOTE_INSN_MAX)
534	  note_flds->opt = create_option (nodot, "default", "");
535	else
536	  note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
537      }
538    note_union_tp = new_structure ("rtx_def_note_subunion", 1,
539				   &lexer_line, note_flds, NULL);
540  }
541  /* Create a type to represent the various forms of SYMBOL_REF_DATA.  */
542  {
543    pair_p sym_flds;
544
545    sym_flds = create_field (NULL, tree_tp, "rt_tree");
546    sym_flds->opt = create_option (nodot, "default", "");
547
548    sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
549    sym_flds->opt = create_option (nodot, "tag", "1");
550
551    symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
552				     &lexer_line, sym_flds, NULL);
553  }
554  for (i = 0; i < NUM_RTX_CODE; i++)
555    {
556      pair_p subfields = NULL;
557      size_t aindex, nmindex;
558      const char *sname;
559      type_p substruct;
560      char *ftag;
561
562      for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
563	{
564	  type_p t;
565	  const char *subname;
566
567	  switch (rtx_format[i][aindex])
568	    {
569	    case '*':
570	    case 'i':
571	    case 'n':
572	    case 'w':
573	      t = scalar_tp;
574	      subname = "rt_int";
575	      break;
576
577	    case '0':
578	      if (i == MEM && aindex == 1)
579		t = mem_attrs_tp, subname = "rt_mem";
580	      else if (i == JUMP_INSN && aindex == 9)
581		t = rtx_tp, subname = "rt_rtx";
582	      else if (i == CODE_LABEL && aindex == 4)
583		t = scalar_tp, subname = "rt_int";
584	      else if (i == CODE_LABEL && aindex == 5)
585		t = rtx_tp, subname = "rt_rtx";
586	      else if (i == LABEL_REF
587		       && (aindex == 1 || aindex == 2))
588		t = rtx_tp, subname = "rt_rtx";
589	      else if (i == NOTE && aindex == 4)
590		t = note_union_tp, subname = "";
591	      else if (i == NOTE && aindex >= 7)
592		t = scalar_tp, subname = "rt_int";
593	      else if (i == ADDR_DIFF_VEC && aindex == 4)
594		t = scalar_tp, subname = "rt_int";
595	      else if (i == VALUE && aindex == 0)
596		t = scalar_tp, subname = "rt_int";
597	      else if (i == REG && aindex == 1)
598		t = scalar_tp, subname = "rt_int";
599	      else if (i == REG && aindex == 2)
600		t = reg_attrs_tp, subname = "rt_reg";
601	      else if (i == SCRATCH && aindex == 0)
602		t = scalar_tp, subname = "rt_int";
603	      else if (i == SYMBOL_REF && aindex == 1)
604		t = scalar_tp, subname = "rt_int";
605	      else if (i == SYMBOL_REF && aindex == 2)
606		t = symbol_union_tp, subname = "";
607	      else if (i == BARRIER && aindex >= 3)
608		t = scalar_tp, subname = "rt_int";
609	      else
610		{
611		  error_at_line (&lexer_line,
612			"rtx type `%s' has `0' in position %lu, can't handle",
613				 rtx_name[i], (unsigned long) aindex);
614		  t = &string_type;
615		  subname = "rt_int";
616		}
617	      break;
618
619	    case 's':
620	    case 'S':
621	    case 'T':
622	      t = &string_type;
623	      subname = "rt_str";
624	      break;
625
626	    case 'e':
627	    case 'u':
628	      t = rtx_tp;
629	      subname = "rt_rtx";
630	      break;
631
632	    case 'E':
633	    case 'V':
634	      t = rtvec_tp;
635	      subname = "rt_rtvec";
636	      break;
637
638	    case 't':
639	      t = tree_tp;
640	      subname = "rt_tree";
641	      break;
642
643	    case 'b':
644	      t = bitmap_tp;
645	      subname = "rt_bit";
646	      break;
647
648	    case 'B':
649	      t = basic_block_tp;
650	      subname = "rt_bb";
651	      break;
652
653	    default:
654	      error_at_line (&lexer_line,
655		     "rtx type `%s' has `%c' in position %lu, can't handle",
656			     rtx_name[i], rtx_format[i][aindex],
657			     (unsigned long)aindex);
658	      t = &string_type;
659	      subname = "rt_int";
660	      break;
661	    }
662
663	  subfields = create_field (subfields, t,
664				    xasprintf (".fld[%lu].%s",
665					       (unsigned long) aindex,
666					       subname));
667	  subfields->opt = nodot;
668	  if (t == note_union_tp)
669	    subfields->opt = create_option (subfields->opt, "desc",
670					    "NOTE_LINE_NUMBER (&%0)");
671	  if (t == symbol_union_tp)
672	    subfields->opt = create_option (subfields->opt, "desc",
673					    "CONSTANT_POOL_ADDRESS_P (&%0)");
674	}
675
676      if (i == SYMBOL_REF)
677	{
678	  /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds.  */
679	  type_p field_tp = find_structure ("block_symbol", 0);
680	  subfields
681	    = create_optional_field (subfields, field_tp, "block_sym",
682				     "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
683	}
684
685      sname = xasprintf ("rtx_def_%s", rtx_name[i]);
686      substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
687
688      ftag = xstrdup (rtx_name[i]);
689      for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
690	ftag[nmindex] = TOUPPER (ftag[nmindex]);
691
692      flds = create_field (flds, substruct, "");
693      flds->opt = create_option (nodot, "tag", ftag);
694    }
695
696  return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
697}
698
699/* Handle `special("tree_exp")'.  This is a special case for
700   field `operands' of struct tree_exp, which although it claims to contain
701   pointers to trees, actually sometimes contains pointers to RTL too.
702   Passed T, the old type of the field, and OPT its options.  Returns
703   a new type for the field.  */
704
705static type_p
706adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
707{
708  pair_p flds;
709  options_p nodot;
710
711  if (t->kind != TYPE_ARRAY)
712    {
713      error_at_line (&lexer_line,
714		     "special `tree_exp' must be applied to an array");
715      return &string_type;
716    }
717
718  nodot = create_option (NULL, "dot", "");
719
720  flds = create_field (NULL, t, "");
721  flds->opt = create_option (nodot, "length",
722			     "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))");
723  flds->opt = create_option (flds->opt, "default", "");
724
725  return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
726}
727
728/* Perform any special processing on a type T, about to become the type
729   of a field.  Return the appropriate type for the field.
730   At present:
731   - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
732   - Similarly for arrays of pointer-to-char;
733   - Converts structures for which a parameter is provided to
734     TYPE_PARAM_STRUCT;
735   - Handles "special" options.
736*/
737
738type_p
739adjust_field_type (type_p t, options_p opt)
740{
741  int length_p = 0;
742  const int pointer_p = t->kind == TYPE_POINTER;
743  type_p params[NUM_PARAM];
744  int params_p = 0;
745  int i;
746
747  for (i = 0; i < NUM_PARAM; i++)
748    params[i] = NULL;
749
750  for (; opt; opt = opt->next)
751    if (strcmp (opt->name, "length") == 0)
752      length_p = 1;
753    else if (strcmp (opt->name, "param_is") == 0
754	     || (strncmp (opt->name, "param", 5) == 0
755		 && ISDIGIT (opt->name[5])
756		 && strcmp (opt->name + 6, "_is") == 0))
757      {
758	int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
759
760	if (! UNION_OR_STRUCT_P (t)
761	    && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
762	  {
763	    error_at_line (&lexer_line,
764   "option `%s' may only be applied to structures or structure pointers",
765			   opt->name);
766	    return t;
767	  }
768
769	params_p = 1;
770	if (params[num] != NULL)
771	  error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
772	if (! ISDIGIT (opt->name[5]))
773	  params[num] = create_pointer ((type_p) opt->info);
774	else
775	  params[num] = (type_p) opt->info;
776      }
777    else if (strcmp (opt->name, "special") == 0)
778      {
779	const char *special_name = opt->info;
780	if (strcmp (special_name, "tree_exp") == 0)
781	  t = adjust_field_tree_exp (t, opt);
782	else if (strcmp (special_name, "rtx_def") == 0)
783	  t = adjust_field_rtx_def (t, opt);
784	else
785	  error_at_line (&lexer_line, "unknown special `%s'", special_name);
786      }
787
788  if (params_p)
789    {
790      type_p realt;
791
792      if (pointer_p)
793	t = t->u.p;
794      realt = find_param_structure (t, params);
795      t = pointer_p ? create_pointer (realt) : realt;
796    }
797
798  if (! length_p
799      && pointer_p
800      && t->u.p->kind == TYPE_SCALAR
801      && (strcmp (t->u.p->u.sc, "char") == 0
802	  || strcmp (t->u.p->u.sc, "unsigned char") == 0))
803    return &string_type;
804  if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
805      && t->u.a.p->u.p->kind == TYPE_SCALAR
806      && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
807	  || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
808    return create_array (&string_type, t->u.a.len);
809
810  return t;
811}
812
813/* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
814   and information about the correspondence between token types and fields
815   in TYPEINFO.  POS is used for error messages.  */
816
817void
818note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
819		struct fileloc *pos)
820{
821  pair_p p;
822  pair_p *p_p;
823
824  for (p = typeinfo; p; p = p->next)
825    {
826      pair_p m;
827
828      if (p->name == NULL)
829	continue;
830
831      if (p->type == (type_p) 1)
832	{
833	  pair_p pp;
834	  int ok = 0;
835
836	  for (pp = typeinfo; pp; pp = pp->next)
837	    if (pp->type != (type_p) 1
838		&& strcmp (pp->opt->info, p->opt->info) == 0)
839	      {
840		ok = 1;
841		break;
842	      }
843	  if (! ok)
844	    continue;
845	}
846
847      for (m = fields; m; m = m->next)
848	if (strcmp (m->name, p->name) == 0)
849	  p->type = m->type;
850      if (p->type == NULL)
851	{
852	  error_at_line (&p->line,
853			 "couldn't match fieldname `%s'", p->name);
854	  p->name = NULL;
855	}
856    }
857
858  p_p = &typeinfo;
859  while (*p_p)
860    {
861      pair_p p = *p_p;
862
863      if (p->name == NULL
864	  || p->type == (type_p) 1)
865	*p_p = p->next;
866      else
867	p_p = &p->next;
868    }
869
870  do_typedef ("YYSTYPE", new_structure ("yy_union", 1, pos, typeinfo, o), pos);
871}
872
873static void process_gc_options (options_p, enum gc_used_enum,
874				int *, int *, int *, type_p *);
875static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
876static void set_gc_used (pair_p);
877
878/* Handle OPT for set_gc_used_type.  */
879
880static void
881process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
882		    int *pass_param, int *length, type_p *nested_ptr)
883{
884  options_p o;
885  for (o = opt; o; o = o->next)
886    if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
887      set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
888    else if (strcmp (o->name, "maybe_undef") == 0)
889      *maybe_undef = 1;
890    else if (strcmp (o->name, "use_params") == 0)
891      *pass_param = 1;
892    else if (strcmp (o->name, "length") == 0)
893      *length = 1;
894    else if (strcmp (o->name, "nested_ptr") == 0)
895      *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
896}
897
898/* Set the gc_used field of T to LEVEL, and handle the types it references.  */
899
900static void
901set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
902{
903  if (t->gc_used >= level)
904    return;
905
906  t->gc_used = level;
907
908  switch (t->kind)
909    {
910    case TYPE_STRUCT:
911    case TYPE_UNION:
912      {
913	pair_p f;
914	int dummy;
915	type_p dummy2;
916
917	process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy,
918			    &dummy2);
919
920	for (f = t->u.s.fields; f; f = f->next)
921	  {
922	    int maybe_undef = 0;
923	    int pass_param = 0;
924	    int length = 0;
925	    type_p nested_ptr = NULL;
926	    process_gc_options (f->opt, level, &maybe_undef, &pass_param,
927				&length, &nested_ptr);
928
929	    if (nested_ptr && f->type->kind == TYPE_POINTER)
930	      set_gc_used_type (nested_ptr, GC_POINTED_TO,
931				pass_param ? param : NULL);
932	    else if (length && f->type->kind == TYPE_POINTER)
933	      set_gc_used_type (f->type->u.p, GC_USED, NULL);
934	    else if (maybe_undef && f->type->kind == TYPE_POINTER)
935	      set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
936	    else if (pass_param && f->type->kind == TYPE_POINTER && param)
937	      set_gc_used_type (find_param_structure (f->type->u.p, param),
938				GC_POINTED_TO, NULL);
939	    else
940	      set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
941	  }
942	break;
943      }
944
945    case TYPE_POINTER:
946      set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
947      break;
948
949    case TYPE_ARRAY:
950      set_gc_used_type (t->u.a.p, GC_USED, param);
951      break;
952
953    case TYPE_LANG_STRUCT:
954      for (t = t->u.s.lang_struct; t; t = t->next)
955	set_gc_used_type (t, level, param);
956      break;
957
958    case TYPE_PARAM_STRUCT:
959      {
960	int i;
961	for (i = 0; i < NUM_PARAM; i++)
962	  if (t->u.param_struct.param[i] != 0)
963	    set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
964      }
965      if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
966	level = GC_POINTED_TO;
967      else
968	level = GC_USED;
969      t->u.param_struct.stru->gc_used = GC_UNUSED;
970      set_gc_used_type (t->u.param_struct.stru, level,
971			t->u.param_struct.param);
972      break;
973
974    default:
975      break;
976    }
977}
978
979/* Set the gc_used fields of all the types pointed to by VARIABLES.  */
980
981static void
982set_gc_used (pair_p variables)
983{
984  pair_p p;
985  for (p = variables; p; p = p->next)
986    set_gc_used_type (p->type, GC_USED, NULL);
987}
988
989/* File mapping routines.  For each input file, there is one output .c file
990   (but some output files have many input files), and there is one .h file
991   for the whole build.  */
992
993/* The list of output files.  */
994static outf_p output_files;
995
996/* The output header file that is included into pretty much every
997   source file.  */
998static outf_p header_file;
999
1000/* Number of files specified in gtfiles.  */
1001#define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
1002
1003/* Number of files in the language files array.  */
1004#define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
1005
1006/* Length of srcdir name.  */
1007static int srcdir_len = 0;
1008
1009#define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1010outf_p base_files[NUM_BASE_FILES];
1011
1012static outf_p create_file (const char *, const char *);
1013static const char * get_file_basename (const char *);
1014
1015/* Create and return an outf_p for a new file for NAME, to be called
1016   ONAME.  */
1017
1018static outf_p
1019create_file (const char *name, const char *oname)
1020{
1021  static const char *const hdr[] = {
1022    "   Copyright (C) 2004 Free Software Foundation, Inc.\n",
1023    "\n",
1024    "This file is part of GCC.\n",
1025    "\n",
1026    "GCC is free software; you can redistribute it and/or modify it under\n",
1027    "the terms of the GNU General Public License as published by the Free\n",
1028    "Software Foundation; either version 2, or (at your option) any later\n",
1029    "version.\n",
1030    "\n",
1031    "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1032    "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1033    "FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n",
1034    "for more details.\n",
1035    "\n",
1036    "You should have received a copy of the GNU General Public License\n",
1037    "along with GCC; see the file COPYING.  If not, write to the Free\n",
1038    "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1039    "02110-1301, USA.  */\n",
1040    "\n",
1041    "/* This file is machine generated.  Do not edit.  */\n"
1042  };
1043  outf_p f;
1044  size_t i;
1045
1046  f = XCNEW (struct outf);
1047  f->next = output_files;
1048  f->name = oname;
1049  output_files = f;
1050
1051  oprintf (f, "/* Type information for %s.\n", name);
1052  for (i = 0; i < ARRAY_SIZE (hdr); i++)
1053    oprintf (f, "%s", hdr[i]);
1054  return f;
1055}
1056
1057/* Print, like fprintf, to O.  */
1058void
1059oprintf (outf_p o, const char *format, ...)
1060{
1061  char *s;
1062  size_t slength;
1063  va_list ap;
1064
1065  va_start (ap, format);
1066  slength = xvasprintf (&s, format, ap);
1067
1068  if (o->bufused + slength > o->buflength)
1069    {
1070      size_t new_len = o->buflength;
1071      if (new_len == 0)
1072	new_len = 1024;
1073      do {
1074	new_len *= 2;
1075      } while (o->bufused + slength >= new_len);
1076      o->buf = XRESIZEVEC (char, o->buf, new_len);
1077      o->buflength = new_len;
1078    }
1079  memcpy (o->buf + o->bufused, s, slength);
1080  o->bufused += slength;
1081  free (s);
1082  va_end (ap);
1083}
1084
1085/* Open the global header file and the language-specific header files.  */
1086
1087static void
1088open_base_files (void)
1089{
1090  size_t i;
1091
1092  header_file = create_file ("GCC", "gtype-desc.h");
1093
1094  for (i = 0; i < NUM_BASE_FILES; i++)
1095    base_files[i] = create_file (lang_dir_names[i],
1096				 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1097
1098  /* gtype-desc.c is a little special, so we create it here.  */
1099  {
1100    /* The order of files here matters very much.  */
1101    static const char *const ifiles [] = {
1102      "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1103      "hashtab.h", "splay-tree.h",  "obstack.h", "bitmap.h", "input.h",
1104      "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1105      "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1106      "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1107      "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1108      "except.h", "output.h", NULL
1109    };
1110    const char *const *ifp;
1111    outf_p gtype_desc_c;
1112
1113    gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1114    for (ifp = ifiles; *ifp; ifp++)
1115      oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1116  }
1117}
1118
1119/* Determine the pathname to F relative to $(srcdir).  */
1120
1121static const char *
1122get_file_basename (const char *f)
1123{
1124  const char *basename;
1125  unsigned i;
1126
1127  basename = strrchr (f, '/');
1128
1129  if (!basename)
1130    return f;
1131
1132  basename++;
1133
1134  for (i = 1; i < NUM_BASE_FILES; i++)
1135    {
1136      const char * s1;
1137      const char * s2;
1138      int l1;
1139      int l2;
1140      s1 = basename - strlen (lang_dir_names [i]) - 1;
1141      s2 = lang_dir_names [i];
1142      l1 = strlen (s1);
1143      l2 = strlen (s2);
1144      if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1145        {
1146          basename -= l2 + 1;
1147          if ((basename - f - 1) != srcdir_len)
1148	    fatal ("filename `%s' should be preceded by $srcdir", f);
1149          break;
1150        }
1151    }
1152
1153  return basename;
1154}
1155
1156/* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1157   INPUT_FILE is used by <lang>.
1158
1159   This function should be written to assume that a file _is_ used
1160   if the situation is unclear.  If it wrongly assumes a file _is_ used,
1161   a linker error will result.  If it wrongly assumes a file _is not_ used,
1162   some GC roots may be missed, which is a much harder-to-debug problem.  */
1163
1164unsigned
1165get_base_file_bitmap (const char *input_file)
1166{
1167  const char *basename = get_file_basename (input_file);
1168  const char *slashpos = strchr (basename, '/');
1169  unsigned j;
1170  unsigned k;
1171  unsigned bitmap;
1172
1173  /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1174     it belongs to the corresponding language.  The file may belong to other
1175     languages as well (which is checked for below).  */
1176
1177  if (slashpos)
1178    {
1179      size_t i;
1180      for (i = 1; i < NUM_BASE_FILES; i++)
1181	if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1182	    && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1183          {
1184            /* It's in a language directory, set that language.  */
1185            bitmap = 1 << i;
1186          }
1187    }
1188
1189  /* If it's in any config-lang.in, then set for the languages
1190     specified.  */
1191
1192  bitmap = 0;
1193
1194  for (j = 0; j < NUM_LANG_FILES; j++)
1195    {
1196      if (!strcmp(input_file, lang_files[j]))
1197        {
1198          for (k = 0; k < NUM_BASE_FILES; k++)
1199            {
1200              if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1201                bitmap |= (1 << k);
1202            }
1203        }
1204    }
1205
1206  /* Otherwise, set all languages.  */
1207  if (!bitmap)
1208    bitmap = (1 << NUM_BASE_FILES) - 1;
1209
1210  return bitmap;
1211}
1212
1213/* An output file, suitable for definitions, that can see declarations
1214   made in INPUT_FILE and is linked into every language that uses
1215   INPUT_FILE.  */
1216
1217outf_p
1218get_output_file_with_visibility (const char *input_file)
1219{
1220  outf_p r;
1221  size_t len;
1222  const char *basename;
1223  const char *for_name;
1224  const char *output_name;
1225
1226  /* This can happen when we need a file with visibility on a
1227     structure that we've never seen.  We have to just hope that it's
1228     globally visible.  */
1229  if (input_file == NULL)
1230    input_file = "system.h";
1231
1232  /* Determine the output file name.  */
1233  basename = get_file_basename (input_file);
1234
1235  len = strlen (basename);
1236  if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1237      || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1238      || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1239    {
1240      char *s;
1241
1242      output_name = s = xasprintf ("gt-%s", basename);
1243      for (; *s != '.'; s++)
1244	if (! ISALNUM (*s) && *s != '-')
1245	  *s = '-';
1246      memcpy (s, ".h", sizeof (".h"));
1247      for_name = basename;
1248    }
1249  /* Some headers get used by more than one front-end; hence, it
1250     would be inappropriate to spew them out to a single gtype-<lang>.h
1251     (and gengtype doesn't know how to direct spewage into multiple
1252     gtype-<lang>.h headers at this time).  Instead, we pair up these
1253     headers with source files (and their special purpose gt-*.h headers).  */
1254  else if (strcmp (basename, "c-common.h") == 0)
1255    output_name = "gt-c-common.h", for_name = "c-common.c";
1256  else if (strcmp (basename, "c-tree.h") == 0)
1257    output_name = "gt-c-decl.h", for_name = "c-decl.c";
1258  else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1259	   && strcmp (basename + 3, "cp-tree.h") == 0)
1260    output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1261  else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1262	   && strcmp (basename + 3, "decl.h") == 0)
1263    output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1264  else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1265	   && strcmp (basename + 3, "name-lookup.h") == 0)
1266    output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1267  else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1268	   && strcmp (basename + 5, "objc-act.h") == 0)
1269    output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1270  else
1271    {
1272      size_t i;
1273
1274      for (i = 0; i < NUM_BASE_FILES; i++)
1275	if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1276	    && basename[strlen(lang_dir_names[i])] == '/')
1277	  return base_files[i];
1278
1279      output_name = "gtype-desc.c";
1280      for_name = NULL;
1281    }
1282
1283  /* Look through to see if we've ever seen this output filename before.  */
1284  for (r = output_files; r; r = r->next)
1285    if (strcmp (r->name, output_name) == 0)
1286      return r;
1287
1288  /* If not, create it.  */
1289  r = create_file (for_name, output_name);
1290
1291  return r;
1292}
1293
1294/* The name of an output file, suitable for definitions, that can see
1295   declarations made in INPUT_FILE and is linked into every language
1296   that uses INPUT_FILE.  */
1297
1298const char *
1299get_output_file_name (const char *input_file)
1300{
1301  return get_output_file_with_visibility (input_file)->name;
1302}
1303
1304/* Copy the output to its final destination,
1305   but don't unnecessarily change modification times.  */
1306
1307static void
1308close_output_files (void)
1309{
1310  outf_p of;
1311
1312  for (of = output_files; of; of = of->next)
1313    {
1314      FILE * newfile;
1315
1316      newfile = fopen (of->name, "r");
1317      if (newfile != NULL )
1318	{
1319	  int no_write_p;
1320	  size_t i;
1321
1322	  for (i = 0; i < of->bufused; i++)
1323	    {
1324	      int ch;
1325	      ch = fgetc (newfile);
1326	      if (ch == EOF || ch != (unsigned char) of->buf[i])
1327		break;
1328	    }
1329	  no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1330	  fclose (newfile);
1331
1332	  if (no_write_p)
1333	    continue;
1334	}
1335
1336      newfile = fopen (of->name, "w");
1337      if (newfile == NULL)
1338	{
1339	  perror ("opening output file");
1340	  exit (1);
1341	}
1342      if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1343	{
1344	  perror ("writing output file");
1345	  exit (1);
1346	}
1347      if (fclose (newfile) != 0)
1348	{
1349	  perror ("closing output file");
1350	  exit (1);
1351	}
1352    }
1353}
1354
1355struct flist {
1356  struct flist *next;
1357  int started_p;
1358  const char *name;
1359  outf_p f;
1360};
1361
1362struct walk_type_data;
1363
1364/* For scalars and strings, given the item in 'val'.
1365   For structures, given a pointer to the item in 'val'.
1366   For misc. pointers, given the item in 'val'.
1367*/
1368typedef void (*process_field_fn)
1369     (type_p f, const struct walk_type_data *p);
1370typedef void (*func_name_fn)
1371     (type_p s, const struct walk_type_data *p);
1372
1373/* Parameters for write_types.  */
1374
1375struct write_types_data
1376{
1377  const char *prefix;
1378  const char *param_prefix;
1379  const char *subfield_marker_routine;
1380  const char *marker_routine;
1381  const char *reorder_note_routine;
1382  const char *comment;
1383};
1384
1385static void output_escaped_param (struct walk_type_data *d,
1386				  const char *, const char *);
1387static void output_mangled_typename (outf_p, type_p);
1388static void walk_type (type_p t, struct walk_type_data *d);
1389static void write_func_for_structure
1390     (type_p orig_s, type_p s, type_p * param,
1391      const struct write_types_data *wtd);
1392static void write_types_process_field
1393     (type_p f, const struct walk_type_data *d);
1394static void write_types (type_p structures,
1395			 type_p param_structs,
1396			 const struct write_types_data *wtd);
1397static void write_types_local_process_field
1398     (type_p f, const struct walk_type_data *d);
1399static void write_local_func_for_structure
1400     (type_p orig_s, type_p s, type_p * param);
1401static void write_local (type_p structures,
1402			 type_p param_structs);
1403static void write_enum_defn (type_p structures, type_p param_structs);
1404static int contains_scalar_p (type_p t);
1405static void put_mangled_filename (outf_p , const char *);
1406static void finish_root_table (struct flist *flp, const char *pfx,
1407			       const char *tname, const char *lastname,
1408			       const char *name);
1409static void write_root (outf_p , pair_p, type_p, const char *, int,
1410			struct fileloc *, const char *);
1411static void write_array (outf_p f, pair_p v,
1412			 const struct write_types_data *wtd);
1413static void write_roots (pair_p);
1414
1415/* Parameters for walk_type.  */
1416
1417struct walk_type_data
1418{
1419  process_field_fn process_field;
1420  const void *cookie;
1421  outf_p of;
1422  options_p opt;
1423  const char *val;
1424  const char *prev_val[4];
1425  int indent;
1426  int counter;
1427  struct fileloc *line;
1428  lang_bitmap bitmap;
1429  type_p *param;
1430  int used_length;
1431  type_p orig_s;
1432  const char *reorder_fn;
1433  bool needs_cast_p;
1434  bool fn_wants_lvalue;
1435};
1436
1437/* Print a mangled name representing T to OF.  */
1438
1439static void
1440output_mangled_typename (outf_p of, type_p t)
1441{
1442  if (t == NULL)
1443    oprintf (of, "Z");
1444  else switch (t->kind)
1445    {
1446    case TYPE_POINTER:
1447      oprintf (of, "P");
1448      output_mangled_typename (of, t->u.p);
1449      break;
1450    case TYPE_SCALAR:
1451      oprintf (of, "I");
1452      break;
1453    case TYPE_STRING:
1454      oprintf (of, "S");
1455      break;
1456    case TYPE_STRUCT:
1457    case TYPE_UNION:
1458    case TYPE_LANG_STRUCT:
1459      oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1460      break;
1461    case TYPE_PARAM_STRUCT:
1462      {
1463	int i;
1464	for (i = 0; i < NUM_PARAM; i++)
1465	  if (t->u.param_struct.param[i] != NULL)
1466	    output_mangled_typename (of, t->u.param_struct.param[i]);
1467	output_mangled_typename (of, t->u.param_struct.stru);
1468      }
1469      break;
1470    case TYPE_ARRAY:
1471      gcc_unreachable ();
1472    }
1473}
1474
1475/* Print PARAM to D->OF processing escapes.  D->VAL references the
1476   current object, D->PREV_VAL the object containing the current
1477   object, ONAME is the name of the option and D->LINE is used to
1478   print error messages.  */
1479
1480static void
1481output_escaped_param (struct walk_type_data *d, const char *param,
1482		      const char *oname)
1483{
1484  const char *p;
1485
1486  for (p = param; *p; p++)
1487    if (*p != '%')
1488      oprintf (d->of, "%c", *p);
1489    else switch (*++p)
1490      {
1491      case 'h':
1492	oprintf (d->of, "(%s)", d->prev_val[2]);
1493	break;
1494      case '0':
1495	oprintf (d->of, "(%s)", d->prev_val[0]);
1496	break;
1497      case '1':
1498	oprintf (d->of, "(%s)", d->prev_val[1]);
1499	break;
1500      case 'a':
1501	{
1502	  const char *pp = d->val + strlen (d->val);
1503	  while (pp[-1] == ']')
1504	    while (*pp != '[')
1505	      pp--;
1506	  oprintf (d->of, "%s", pp);
1507	}
1508	break;
1509      default:
1510	error_at_line (d->line, "`%s' option contains bad escape %c%c",
1511		       oname, '%', *p);
1512      }
1513}
1514
1515/* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1516   which is of type T.  Write code to D->OF to constrain execution (at
1517   the point that D->PROCESS_FIELD is called) to the appropriate
1518   cases.  Call D->PROCESS_FIELD on subobjects before calling it on
1519   pointers to those objects.  D->PREV_VAL lists the objects
1520   containing the current object, D->OPT is a list of options to
1521   apply, D->INDENT is the current indentation level, D->LINE is used
1522   to print error messages, D->BITMAP indicates which languages to
1523   print the structure for, and D->PARAM is the current parameter
1524   (from an enclosing param_is option).  */
1525
1526static void
1527walk_type (type_p t, struct walk_type_data *d)
1528{
1529  const char *length = NULL;
1530  const char *desc = NULL;
1531  int maybe_undef_p = 0;
1532  int use_param_num = -1;
1533  int use_params_p = 0;
1534  options_p oo;
1535  const struct nested_ptr_data *nested_ptr_d = NULL;
1536
1537  d->needs_cast_p = false;
1538  for (oo = d->opt; oo; oo = oo->next)
1539    if (strcmp (oo->name, "length") == 0)
1540      length = oo->info;
1541    else if (strcmp (oo->name, "maybe_undef") == 0)
1542      maybe_undef_p = 1;
1543    else if (strncmp (oo->name, "use_param", 9) == 0
1544	     && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1545      use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1546    else if (strcmp (oo->name, "use_params") == 0)
1547      use_params_p = 1;
1548    else if (strcmp (oo->name, "desc") == 0)
1549      desc = oo->info;
1550    else if (strcmp (oo->name, "nested_ptr") == 0)
1551      nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1552    else if (strcmp (oo->name, "dot") == 0)
1553      ;
1554    else if (strcmp (oo->name, "tag") == 0)
1555      ;
1556    else if (strcmp (oo->name, "special") == 0)
1557      ;
1558    else if (strcmp (oo->name, "skip") == 0)
1559      ;
1560    else if (strcmp (oo->name, "default") == 0)
1561      ;
1562    else if (strcmp (oo->name, "descbits") == 0)
1563      ;
1564    else if (strcmp (oo->name, "param_is") == 0)
1565      ;
1566    else if (strncmp (oo->name, "param", 5) == 0
1567	     && ISDIGIT (oo->name[5])
1568	     && strcmp (oo->name + 6, "_is") == 0)
1569      ;
1570    else if (strcmp (oo->name, "chain_next") == 0)
1571      ;
1572    else if (strcmp (oo->name, "chain_prev") == 0)
1573      ;
1574    else if (strcmp (oo->name, "reorder") == 0)
1575      ;
1576    else
1577      error_at_line (d->line, "unknown option `%s'\n", oo->name);
1578
1579  if (d->used_length)
1580    length = NULL;
1581
1582  if (use_params_p)
1583    {
1584      int pointer_p = t->kind == TYPE_POINTER;
1585
1586      if (pointer_p)
1587	t = t->u.p;
1588      if (! UNION_OR_STRUCT_P (t))
1589	error_at_line (d->line, "`use_params' option on unimplemented type");
1590      else
1591	t = find_param_structure (t, d->param);
1592      if (pointer_p)
1593	t = create_pointer (t);
1594    }
1595
1596  if (use_param_num != -1)
1597    {
1598      if (d->param != NULL && d->param[use_param_num] != NULL)
1599	{
1600	  type_p nt = d->param[use_param_num];
1601
1602	  if (t->kind == TYPE_ARRAY)
1603	    nt = create_array (nt, t->u.a.len);
1604	  else if (length != NULL && t->kind == TYPE_POINTER)
1605	    nt = create_pointer (nt);
1606	  d->needs_cast_p = (t->kind != TYPE_POINTER
1607			     && (nt->kind == TYPE_POINTER
1608				 || nt->kind == TYPE_STRING));
1609	  t = nt;
1610	}
1611      else
1612	error_at_line (d->line, "no parameter defined for `%s'",
1613		       d->val);
1614    }
1615
1616  if (maybe_undef_p
1617      && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1618    {
1619      error_at_line (d->line,
1620		     "field `%s' has invalid option `maybe_undef_p'\n",
1621		     d->val);
1622      return;
1623    }
1624
1625  switch (t->kind)
1626    {
1627    case TYPE_SCALAR:
1628    case TYPE_STRING:
1629      d->process_field (t, d);
1630      break;
1631
1632    case TYPE_POINTER:
1633      {
1634	if (maybe_undef_p
1635	    && t->u.p->u.s.line.file == NULL)
1636	  {
1637	    oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1638	    break;
1639	  }
1640
1641	if (! length)
1642	  {
1643	    if (! UNION_OR_STRUCT_P (t->u.p)
1644		&& t->u.p->kind != TYPE_PARAM_STRUCT)
1645	      {
1646		error_at_line (d->line,
1647			       "field `%s' is pointer to unimplemented type",
1648			       d->val);
1649		break;
1650	      }
1651
1652	    if (nested_ptr_d)
1653	      {
1654		const char *oldprevval2 = d->prev_val[2];
1655
1656		if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1657		  {
1658		    error_at_line (d->line,
1659				   "field `%s' has invalid "
1660				   "option `nested_ptr'\n",
1661				   d->val);
1662		    return;
1663		  }
1664
1665		d->prev_val[2] = d->val;
1666		oprintf (d->of, "%*s{\n", d->indent, "");
1667		d->indent += 2;
1668		d->val = xasprintf ("x%d", d->counter++);
1669		oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1670			 (nested_ptr_d->type->kind == TYPE_UNION
1671			  ? "union" : "struct"),
1672			 nested_ptr_d->type->u.s.tag,
1673			 d->fn_wants_lvalue ? "" : "const ",
1674			 d->val);
1675		oprintf (d->of, "%*s", d->indent + 2, "");
1676		output_escaped_param (d, nested_ptr_d->convert_from,
1677				      "nested_ptr");
1678		oprintf (d->of, ";\n");
1679
1680		d->process_field (nested_ptr_d->type, d);
1681
1682		if (d->fn_wants_lvalue)
1683		  {
1684		    oprintf (d->of, "%*s%s = ", d->indent, "",
1685			     d->prev_val[2]);
1686		    d->prev_val[2] = d->val;
1687		    output_escaped_param (d, nested_ptr_d->convert_to,
1688					  "nested_ptr");
1689		    oprintf (d->of, ";\n");
1690		  }
1691
1692		d->indent -= 2;
1693		oprintf (d->of, "%*s}\n", d->indent, "");
1694		d->val = d->prev_val[2];
1695		d->prev_val[2] = oldprevval2;
1696	      }
1697	    else
1698	      d->process_field (t->u.p, d);
1699	  }
1700	else
1701	  {
1702	    int loopcounter = d->counter++;
1703	    const char *oldval = d->val;
1704	    const char *oldprevval3 = d->prev_val[3];
1705	    char *newval;
1706
1707	    oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1708	    d->indent += 2;
1709	    oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1710	    oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1711		     loopcounter, loopcounter);
1712	    output_escaped_param (d, length, "length");
1713	    oprintf (d->of, "); i%d++) {\n", loopcounter);
1714	    d->indent += 2;
1715	    d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1716	    d->used_length = 1;
1717	    d->prev_val[3] = oldval;
1718	    walk_type (t->u.p, d);
1719	    free (newval);
1720	    d->val = oldval;
1721	    d->prev_val[3] = oldprevval3;
1722	    d->used_length = 0;
1723	    d->indent -= 2;
1724	    oprintf (d->of, "%*s}\n", d->indent, "");
1725	    d->process_field(t, d);
1726	    d->indent -= 2;
1727	    oprintf (d->of, "%*s}\n", d->indent, "");
1728	  }
1729      }
1730      break;
1731
1732    case TYPE_ARRAY:
1733      {
1734	int loopcounter = d->counter++;
1735	const char *oldval = d->val;
1736	char *newval;
1737
1738	/* If it's an array of scalars, we optimize by not generating
1739	   any code.  */
1740	if (t->u.a.p->kind == TYPE_SCALAR)
1741	  break;
1742
1743	oprintf (d->of, "%*s{\n", d->indent, "");
1744	d->indent += 2;
1745	oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1746	oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1747		 loopcounter, loopcounter);
1748	if (length)
1749	  output_escaped_param (d, length, "length");
1750	else
1751	  oprintf (d->of, "%s", t->u.a.len);
1752	oprintf (d->of, "); i%d++) {\n", loopcounter);
1753	d->indent += 2;
1754	d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1755	d->used_length = 1;
1756	walk_type (t->u.a.p, d);
1757	free (newval);
1758	d->used_length = 0;
1759	d->val = oldval;
1760	d->indent -= 2;
1761	oprintf (d->of, "%*s}\n", d->indent, "");
1762	d->indent -= 2;
1763	oprintf (d->of, "%*s}\n", d->indent, "");
1764      }
1765      break;
1766
1767    case TYPE_STRUCT:
1768    case TYPE_UNION:
1769      {
1770	pair_p f;
1771	const char *oldval = d->val;
1772	const char *oldprevval1 = d->prev_val[1];
1773	const char *oldprevval2 = d->prev_val[2];
1774	const int union_p = t->kind == TYPE_UNION;
1775	int seen_default_p = 0;
1776	options_p o;
1777
1778	if (! t->u.s.line.file)
1779	  error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1780
1781	if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1782	  {
1783	    error_at_line (d->line,
1784			   "structure `%s' defined for mismatching languages",
1785			   t->u.s.tag);
1786	    error_at_line (&t->u.s.line, "one structure defined here");
1787	  }
1788
1789	/* Some things may also be defined in the structure's options.  */
1790	for (o = t->u.s.opt; o; o = o->next)
1791	  if (! desc && strcmp (o->name, "desc") == 0)
1792	    desc = o->info;
1793
1794	d->prev_val[2] = oldval;
1795	d->prev_val[1] = oldprevval2;
1796	if (union_p)
1797	  {
1798	    if (desc == NULL)
1799	      {
1800		error_at_line (d->line, "missing `desc' option for union `%s'",
1801			       t->u.s.tag);
1802		desc = "1";
1803	      }
1804	    oprintf (d->of, "%*sswitch (", d->indent, "");
1805	    output_escaped_param (d, desc, "desc");
1806	    oprintf (d->of, ")\n");
1807	    d->indent += 2;
1808	    oprintf (d->of, "%*s{\n", d->indent, "");
1809	  }
1810	for (f = t->u.s.fields; f; f = f->next)
1811	  {
1812	    options_p oo;
1813	    const char *dot = ".";
1814	    const char *tagid = NULL;
1815	    int skip_p = 0;
1816	    int default_p = 0;
1817	    int use_param_p = 0;
1818	    char *newval;
1819
1820	    d->reorder_fn = NULL;
1821	    for (oo = f->opt; oo; oo = oo->next)
1822	      if (strcmp (oo->name, "dot") == 0)
1823		dot = oo->info;
1824	      else if (strcmp (oo->name, "tag") == 0)
1825		tagid = oo->info;
1826	      else if (strcmp (oo->name, "skip") == 0)
1827		skip_p = 1;
1828	      else if (strcmp (oo->name, "default") == 0)
1829		default_p = 1;
1830	      else if (strcmp (oo->name, "reorder") == 0)
1831		d->reorder_fn = oo->info;
1832	      else if (strncmp (oo->name, "use_param", 9) == 0
1833		       && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1834		use_param_p = 1;
1835
1836	    if (skip_p)
1837	      continue;
1838
1839	    if (union_p && tagid)
1840	      {
1841		oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1842		d->indent += 2;
1843	      }
1844	    else if (union_p && default_p)
1845	      {
1846		oprintf (d->of, "%*sdefault:\n", d->indent, "");
1847		d->indent += 2;
1848		seen_default_p = 1;
1849	      }
1850	    else if (! union_p && (default_p || tagid))
1851	      error_at_line (d->line,
1852			     "can't use `%s' outside a union on field `%s'",
1853			     default_p ? "default" : "tag", f->name);
1854	    else if (union_p && ! (default_p || tagid)
1855		     && f->type->kind == TYPE_SCALAR)
1856	      {
1857		fprintf (stderr,
1858	"%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1859			 d->line->file, d->line->line, f->name);
1860		continue;
1861	      }
1862	    else if (union_p && ! (default_p || tagid))
1863	      error_at_line (d->line,
1864			     "field `%s' is missing `tag' or `default' option",
1865			     f->name);
1866
1867	    d->line = &f->line;
1868	    d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1869	    d->opt = f->opt;
1870	    d->used_length = false;
1871
1872	    if (union_p && use_param_p && d->param == NULL)
1873	      oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1874	    else
1875	      walk_type (f->type, d);
1876
1877	    free (newval);
1878
1879	    if (union_p)
1880	      {
1881		oprintf (d->of, "%*sbreak;\n", d->indent, "");
1882		d->indent -= 2;
1883	      }
1884	  }
1885	d->reorder_fn = NULL;
1886
1887	d->val = oldval;
1888	d->prev_val[1] = oldprevval1;
1889	d->prev_val[2] = oldprevval2;
1890
1891	if (union_p && ! seen_default_p)
1892	  {
1893	    oprintf (d->of, "%*sdefault:\n", d->indent, "");
1894	    oprintf (d->of, "%*s  break;\n", d->indent, "");
1895	  }
1896	if (union_p)
1897	  {
1898	    oprintf (d->of, "%*s}\n", d->indent, "");
1899	    d->indent -= 2;
1900	  }
1901      }
1902      break;
1903
1904    case TYPE_LANG_STRUCT:
1905      {
1906	type_p nt;
1907	for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1908	  if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1909	    break;
1910	if (nt == NULL)
1911	  error_at_line (d->line, "structure `%s' differs between languages",
1912			 t->u.s.tag);
1913	else
1914	  walk_type (nt, d);
1915      }
1916      break;
1917
1918    case TYPE_PARAM_STRUCT:
1919      {
1920	type_p *oldparam = d->param;
1921
1922	d->param = t->u.param_struct.param;
1923	walk_type (t->u.param_struct.stru, d);
1924	d->param = oldparam;
1925      }
1926      break;
1927
1928    default:
1929      gcc_unreachable ();
1930    }
1931}
1932
1933/* process_field routine for marking routines.  */
1934
1935static void
1936write_types_process_field (type_p f, const struct walk_type_data *d)
1937{
1938  const struct write_types_data *wtd;
1939  const char *cast = d->needs_cast_p ? "(void *)" : "";
1940  wtd = (const struct write_types_data *) d->cookie;
1941
1942  switch (f->kind)
1943    {
1944    case TYPE_POINTER:
1945      oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1946	       wtd->subfield_marker_routine, cast, d->val);
1947      if (wtd->param_prefix)
1948	{
1949	  oprintf (d->of, ", %s", d->prev_val[3]);
1950	  if (d->orig_s)
1951	    {
1952	      oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1953	      output_mangled_typename (d->of, d->orig_s);
1954	    }
1955	  else
1956	    oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1957
1958	  if (f->u.p->kind == TYPE_PARAM_STRUCT
1959	      && f->u.p->u.s.line.file != NULL)
1960	    {
1961	      oprintf (d->of, ", gt_e_");
1962	      output_mangled_typename (d->of, f);
1963	    }
1964	  else if (UNION_OR_STRUCT_P (f)
1965		   && f->u.p->u.s.line.file != NULL)
1966	    {
1967	      oprintf (d->of, ", gt_ggc_e_");
1968	      output_mangled_typename (d->of, f);
1969	    }
1970	  else
1971	    oprintf (d->of, ", gt_types_enum_last");
1972	}
1973      oprintf (d->of, ");\n");
1974      if (d->reorder_fn && wtd->reorder_note_routine)
1975	oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1976		 wtd->reorder_note_routine, cast, d->val,
1977		 d->prev_val[3], d->reorder_fn);
1978      break;
1979
1980    case TYPE_STRING:
1981      if (wtd->param_prefix == NULL)
1982	break;
1983
1984    case TYPE_STRUCT:
1985    case TYPE_UNION:
1986    case TYPE_LANG_STRUCT:
1987    case TYPE_PARAM_STRUCT:
1988      oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1989      output_mangled_typename (d->of, f);
1990      oprintf (d->of, " (%s%s);\n", cast, d->val);
1991      if (d->reorder_fn && wtd->reorder_note_routine)
1992	oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1993		 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1994		 d->reorder_fn);
1995      break;
1996
1997    case TYPE_SCALAR:
1998      break;
1999
2000    default:
2001      gcc_unreachable ();
2002    }
2003}
2004
2005/* A subroutine of write_func_for_structure.  Write the enum tag for S.  */
2006
2007static void
2008output_type_enum (outf_p of, type_p s)
2009{
2010  if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2011    {
2012      oprintf (of, ", gt_e_");
2013      output_mangled_typename (of, s);
2014    }
2015  else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2016    {
2017      oprintf (of, ", gt_ggc_e_");
2018      output_mangled_typename (of, s);
2019    }
2020  else
2021    oprintf (of, ", gt_types_enum_last");
2022}
2023
2024/* For S, a structure that's part of ORIG_S, and using parameters
2025   PARAM, write out a routine that:
2026   - Takes a parameter, a void * but actually of type *S
2027   - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2028     field of S or its substructures and (in some cases) things
2029     that are pointed to by S.
2030*/
2031
2032static void
2033write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2034			  const struct write_types_data *wtd)
2035{
2036  const char *fn = s->u.s.line.file;
2037  int i;
2038  const char *chain_next = NULL;
2039  const char *chain_prev = NULL;
2040  options_p opt;
2041  struct walk_type_data d;
2042
2043  /* This is a hack, and not the good kind either.  */
2044  for (i = NUM_PARAM - 1; i >= 0; i--)
2045    if (param && param[i] && param[i]->kind == TYPE_POINTER
2046	&& UNION_OR_STRUCT_P (param[i]->u.p))
2047      fn = param[i]->u.p->u.s.line.file;
2048
2049  memset (&d, 0, sizeof (d));
2050  d.of = get_output_file_with_visibility (fn);
2051
2052  for (opt = s->u.s.opt; opt; opt = opt->next)
2053    if (strcmp (opt->name, "chain_next") == 0)
2054      chain_next = opt->info;
2055    else if (strcmp (opt->name, "chain_prev") == 0)
2056      chain_prev = opt->info;
2057
2058  if (chain_prev != NULL && chain_next == NULL)
2059    error_at_line (&s->u.s.line, "chain_prev without chain_next");
2060
2061  d.process_field = write_types_process_field;
2062  d.cookie = wtd;
2063  d.orig_s = orig_s;
2064  d.opt = s->u.s.opt;
2065  d.line = &s->u.s.line;
2066  d.bitmap = s->u.s.bitmap;
2067  d.param = param;
2068  d.prev_val[0] = "*x";
2069  d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2070  d.prev_val[3] = "x";
2071  d.val = "(*x)";
2072
2073  oprintf (d.of, "\n");
2074  oprintf (d.of, "void\n");
2075  if (param == NULL)
2076    oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2077  else
2078    {
2079      oprintf (d.of, "gt_%s_", wtd->prefix);
2080      output_mangled_typename (d.of, orig_s);
2081    }
2082  oprintf (d.of, " (void *x_p)\n");
2083  oprintf (d.of, "{\n");
2084  oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2085	   s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2086	   chain_next == NULL ? "const " : "",
2087	   s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2088  if (chain_next != NULL)
2089    oprintf (d.of, "  %s %s * xlimit = x;\n",
2090	     s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2091  if (chain_next == NULL)
2092    {
2093      oprintf (d.of, "  if (%s (x", wtd->marker_routine);
2094      if (wtd->param_prefix)
2095	{
2096	  oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2097	  output_mangled_typename (d.of, orig_s);
2098	  output_type_enum (d.of, orig_s);
2099	}
2100      oprintf (d.of, "))\n");
2101    }
2102  else
2103    {
2104      oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2105      if (wtd->param_prefix)
2106	{
2107	  oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2108	  output_mangled_typename (d.of, orig_s);
2109	  output_type_enum (d.of, orig_s);
2110	}
2111      oprintf (d.of, "))\n");
2112      oprintf (d.of, "   xlimit = (");
2113      d.prev_val[2] = "*xlimit";
2114      output_escaped_param (&d, chain_next, "chain_next");
2115      oprintf (d.of, ");\n");
2116      if (chain_prev != NULL)
2117	{
2118	  oprintf (d.of, "  if (x != xlimit)\n");
2119	  oprintf (d.of, "    for (;;)\n");
2120	  oprintf (d.of, "      {\n");
2121	  oprintf (d.of, "        %s %s * const xprev = (",
2122		   s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2123
2124	  d.prev_val[2] = "*x";
2125	  output_escaped_param (&d, chain_prev, "chain_prev");
2126	  oprintf (d.of, ");\n");
2127	  oprintf (d.of, "        if (xprev == NULL) break;\n");
2128	  oprintf (d.of, "        x = xprev;\n");
2129	  oprintf (d.of, "        (void) %s (xprev",
2130		   wtd->marker_routine);
2131	  if (wtd->param_prefix)
2132	    {
2133	      oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2134	      output_mangled_typename (d.of, orig_s);
2135	      output_type_enum (d.of, orig_s);
2136	    }
2137	  oprintf (d.of, ");\n");
2138	  oprintf (d.of, "      }\n");
2139	}
2140      oprintf (d.of, "  while (x != xlimit)\n");
2141    }
2142  oprintf (d.of, "    {\n");
2143
2144  d.prev_val[2] = "*x";
2145  d.indent = 6;
2146  walk_type (s, &d);
2147
2148  if (chain_next != NULL)
2149    {
2150      oprintf (d.of, "      x = (");
2151      output_escaped_param (&d, chain_next, "chain_next");
2152      oprintf (d.of, ");\n");
2153    }
2154
2155  oprintf (d.of, "    }\n");
2156  oprintf (d.of, "}\n");
2157}
2158
2159/* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2160
2161static void
2162write_types (type_p structures, type_p param_structs,
2163	     const struct write_types_data *wtd)
2164{
2165  type_p s;
2166
2167  oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2168  for (s = structures; s; s = s->next)
2169    if (s->gc_used == GC_POINTED_TO
2170	|| s->gc_used == GC_MAYBE_POINTED_TO)
2171      {
2172	options_p opt;
2173
2174	if (s->gc_used == GC_MAYBE_POINTED_TO
2175	    && s->u.s.line.file == NULL)
2176	  continue;
2177
2178	oprintf (header_file, "#define gt_%s_", wtd->prefix);
2179	output_mangled_typename (header_file, s);
2180	oprintf (header_file, "(X) do { \\\n");
2181	oprintf (header_file,
2182		 "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2183		 s->u.s.tag);
2184	oprintf (header_file,
2185		 "  } while (0)\n");
2186
2187	for (opt = s->u.s.opt; opt; opt = opt->next)
2188	  if (strcmp (opt->name, "ptr_alias") == 0)
2189	    {
2190	      type_p t = (type_p) opt->info;
2191	      if (t->kind == TYPE_STRUCT
2192		  || t->kind == TYPE_UNION
2193		  || t->kind == TYPE_LANG_STRUCT)
2194		oprintf (header_file,
2195			 "#define gt_%sx_%s gt_%sx_%s\n",
2196			 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2197	      else
2198		error_at_line (&s->u.s.line,
2199			       "structure alias is not a structure");
2200	      break;
2201	    }
2202	if (opt)
2203	  continue;
2204
2205	/* Declare the marker procedure only once.  */
2206	oprintf (header_file,
2207		 "extern void gt_%sx_%s (void *);\n",
2208		 wtd->prefix, s->u.s.tag);
2209
2210	if (s->u.s.line.file == NULL)
2211	  {
2212	    fprintf (stderr, "warning: structure `%s' used but not defined\n",
2213		     s->u.s.tag);
2214	    continue;
2215	  }
2216
2217	if (s->kind == TYPE_LANG_STRUCT)
2218	  {
2219	    type_p ss;
2220	    for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2221	      write_func_for_structure (s, ss, NULL, wtd);
2222	  }
2223	else
2224	  write_func_for_structure (s, s, NULL, wtd);
2225      }
2226
2227  for (s = param_structs; s; s = s->next)
2228    if (s->gc_used == GC_POINTED_TO)
2229      {
2230	type_p * param = s->u.param_struct.param;
2231	type_p stru = s->u.param_struct.stru;
2232
2233	/* Declare the marker procedure.  */
2234	oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2235	output_mangled_typename (header_file, s);
2236	oprintf (header_file, " (void *);\n");
2237
2238	if (stru->u.s.line.file == NULL)
2239	  {
2240	    fprintf (stderr, "warning: structure `%s' used but not defined\n",
2241		     s->u.s.tag);
2242	    continue;
2243	  }
2244
2245	if (stru->kind == TYPE_LANG_STRUCT)
2246	  {
2247	    type_p ss;
2248	    for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2249	      write_func_for_structure (s, ss, param, wtd);
2250	  }
2251	else
2252	  write_func_for_structure (s, stru, param, wtd);
2253      }
2254}
2255
2256static const struct write_types_data ggc_wtd =
2257{
2258  "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2259  "GC marker procedures.  "
2260};
2261
2262static const struct write_types_data pch_wtd =
2263{
2264  "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2265  "gt_pch_note_reorder",
2266  "PCH type-walking procedures.  "
2267};
2268
2269/* Write out the local pointer-walking routines.  */
2270
2271/* process_field routine for local pointer-walking.  */
2272
2273static void
2274write_types_local_process_field (type_p f, const struct walk_type_data *d)
2275{
2276  switch (f->kind)
2277    {
2278    case TYPE_POINTER:
2279    case TYPE_STRUCT:
2280    case TYPE_UNION:
2281    case TYPE_LANG_STRUCT:
2282    case TYPE_PARAM_STRUCT:
2283    case TYPE_STRING:
2284      oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2285	       d->prev_val[3]);
2286      oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
2287      break;
2288
2289    case TYPE_SCALAR:
2290      break;
2291
2292    default:
2293      gcc_unreachable ();
2294    }
2295}
2296
2297/* For S, a structure that's part of ORIG_S, and using parameters
2298   PARAM, write out a routine that:
2299   - Is of type gt_note_pointers
2300   - Calls PROCESS_FIELD on each field of S or its substructures.
2301*/
2302
2303static void
2304write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2305{
2306  const char *fn = s->u.s.line.file;
2307  int i;
2308  struct walk_type_data d;
2309
2310  /* This is a hack, and not the good kind either.  */
2311  for (i = NUM_PARAM - 1; i >= 0; i--)
2312    if (param && param[i] && param[i]->kind == TYPE_POINTER
2313	&& UNION_OR_STRUCT_P (param[i]->u.p))
2314      fn = param[i]->u.p->u.s.line.file;
2315
2316  memset (&d, 0, sizeof (d));
2317  d.of = get_output_file_with_visibility (fn);
2318
2319  d.process_field = write_types_local_process_field;
2320  d.opt = s->u.s.opt;
2321  d.line = &s->u.s.line;
2322  d.bitmap = s->u.s.bitmap;
2323  d.param = param;
2324  d.prev_val[0] = d.prev_val[2] = "*x";
2325  d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2326  d.prev_val[3] = "x";
2327  d.val = "(*x)";
2328  d.fn_wants_lvalue = true;
2329
2330  oprintf (d.of, "\n");
2331  oprintf (d.of, "void\n");
2332  oprintf (d.of, "gt_pch_p_");
2333  output_mangled_typename (d.of, orig_s);
2334  oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2335	   "\tvoid *x_p,\n"
2336	   "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2337	   "\tATTRIBUTE_UNUSED void *cookie)\n");
2338  oprintf (d.of, "{\n");
2339  oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2340	   s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2341	   s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2342  d.indent = 2;
2343  walk_type (s, &d);
2344  oprintf (d.of, "}\n");
2345}
2346
2347/* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
2348
2349static void
2350write_local (type_p structures, type_p param_structs)
2351{
2352  type_p s;
2353
2354  oprintf (header_file, "\n/* Local pointer-walking routines.  */\n");
2355  for (s = structures; s; s = s->next)
2356    if (s->gc_used == GC_POINTED_TO
2357	|| s->gc_used == GC_MAYBE_POINTED_TO)
2358      {
2359	options_p opt;
2360
2361	if (s->u.s.line.file == NULL)
2362	  continue;
2363
2364	for (opt = s->u.s.opt; opt; opt = opt->next)
2365	  if (strcmp (opt->name, "ptr_alias") == 0)
2366	    {
2367	      type_p t = (type_p) opt->info;
2368	      if (t->kind == TYPE_STRUCT
2369		  || t->kind == TYPE_UNION
2370		  || t->kind == TYPE_LANG_STRUCT)
2371		{
2372		  oprintf (header_file, "#define gt_pch_p_");
2373		  output_mangled_typename (header_file, s);
2374		  oprintf (header_file, " gt_pch_p_");
2375		  output_mangled_typename (header_file, t);
2376		  oprintf (header_file, "\n");
2377		}
2378	      else
2379		error_at_line (&s->u.s.line,
2380			       "structure alias is not a structure");
2381	      break;
2382	    }
2383	if (opt)
2384	  continue;
2385
2386	/* Declare the marker procedure only once.  */
2387	oprintf (header_file, "extern void gt_pch_p_");
2388	output_mangled_typename (header_file, s);
2389	oprintf (header_file,
2390	 "\n    (void *, void *, gt_pointer_operator, void *);\n");
2391
2392	if (s->kind == TYPE_LANG_STRUCT)
2393	  {
2394	    type_p ss;
2395	    for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2396	      write_local_func_for_structure (s, ss, NULL);
2397	  }
2398	else
2399	  write_local_func_for_structure (s, s, NULL);
2400      }
2401
2402  for (s = param_structs; s; s = s->next)
2403    if (s->gc_used == GC_POINTED_TO)
2404      {
2405	type_p * param = s->u.param_struct.param;
2406	type_p stru = s->u.param_struct.stru;
2407
2408	/* Declare the marker procedure.  */
2409	oprintf (header_file, "extern void gt_pch_p_");
2410	output_mangled_typename (header_file, s);
2411	oprintf (header_file,
2412	 "\n    (void *, void *, gt_pointer_operator, void *);\n");
2413
2414	if (stru->u.s.line.file == NULL)
2415	  {
2416	    fprintf (stderr, "warning: structure `%s' used but not defined\n",
2417		     s->u.s.tag);
2418	    continue;
2419	  }
2420
2421	if (stru->kind == TYPE_LANG_STRUCT)
2422	  {
2423	    type_p ss;
2424	    for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2425	      write_local_func_for_structure (s, ss, param);
2426	  }
2427	else
2428	  write_local_func_for_structure (s, stru, param);
2429      }
2430}
2431
2432/* Write out the 'enum' definition for gt_types_enum.  */
2433
2434static void
2435write_enum_defn (type_p structures, type_p param_structs)
2436{
2437  type_p s;
2438
2439  oprintf (header_file, "\n/* Enumeration of types known.  */\n");
2440  oprintf (header_file, "enum gt_types_enum {\n");
2441  for (s = structures; s; s = s->next)
2442    if (s->gc_used == GC_POINTED_TO
2443	|| s->gc_used == GC_MAYBE_POINTED_TO)
2444      {
2445	if (s->gc_used == GC_MAYBE_POINTED_TO
2446	    && s->u.s.line.file == NULL)
2447	  continue;
2448
2449	oprintf (header_file, " gt_ggc_e_");
2450	output_mangled_typename (header_file, s);
2451	oprintf (header_file, ", \n");
2452      }
2453  for (s = param_structs; s; s = s->next)
2454    if (s->gc_used == GC_POINTED_TO)
2455      {
2456	oprintf (header_file, " gt_e_");
2457	output_mangled_typename (header_file, s);
2458	oprintf (header_file, ", \n");
2459      }
2460  oprintf (header_file, " gt_types_enum_last\n");
2461  oprintf (header_file, "};\n");
2462}
2463
2464/* Might T contain any non-pointer elements?  */
2465
2466static int
2467contains_scalar_p (type_p t)
2468{
2469  switch (t->kind)
2470    {
2471    case TYPE_STRING:
2472    case TYPE_POINTER:
2473      return 0;
2474    case TYPE_ARRAY:
2475      return contains_scalar_p (t->u.a.p);
2476    default:
2477      /* Could also check for structures that have no non-pointer
2478	 fields, but there aren't enough of those to worry about.  */
2479      return 1;
2480    }
2481}
2482
2483/* Mangle FN and print it to F.  */
2484
2485static void
2486put_mangled_filename (outf_p f, const char *fn)
2487{
2488  const char *name = get_output_file_name (fn);
2489  for (; *name != 0; name++)
2490    if (ISALNUM (*name))
2491      oprintf (f, "%c", *name);
2492    else
2493      oprintf (f, "%c", '_');
2494}
2495
2496/* Finish off the currently-created root tables in FLP.  PFX, TNAME,
2497   LASTNAME, and NAME are all strings to insert in various places in
2498   the resulting code.  */
2499
2500static void
2501finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2502		   const char *tname, const char *name)
2503{
2504  struct flist *fli2;
2505
2506  for (fli2 = flp; fli2; fli2 = fli2->next)
2507    if (fli2->started_p)
2508      {
2509	oprintf (fli2->f, "  %s\n", lastname);
2510	oprintf (fli2->f, "};\n\n");
2511      }
2512
2513  for (fli2 = flp; fli2; fli2 = fli2->next)
2514    if (fli2->started_p)
2515      {
2516	lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2517	int fnum;
2518
2519	for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2520	  if (bitmap & 1)
2521	    {
2522	      oprintf (base_files[fnum],
2523		       "extern const struct %s gt_%s_",
2524		       tname, pfx);
2525	      put_mangled_filename (base_files[fnum], fli2->name);
2526	      oprintf (base_files[fnum], "[];\n");
2527	    }
2528      }
2529
2530  {
2531    size_t fnum;
2532    for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2533      oprintf (base_files [fnum],
2534	       "const struct %s * const %s[] = {\n",
2535	       tname, name);
2536  }
2537
2538
2539  for (fli2 = flp; fli2; fli2 = fli2->next)
2540    if (fli2->started_p)
2541      {
2542	lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2543	int fnum;
2544
2545	fli2->started_p = 0;
2546
2547	for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2548	  if (bitmap & 1)
2549	    {
2550	      oprintf (base_files[fnum], "  gt_%s_", pfx);
2551	      put_mangled_filename (base_files[fnum], fli2->name);
2552	      oprintf (base_files[fnum], ",\n");
2553	    }
2554      }
2555
2556  {
2557    size_t fnum;
2558    for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2559      {
2560	oprintf (base_files[fnum], "  NULL\n");
2561	oprintf (base_files[fnum], "};\n");
2562      }
2563  }
2564}
2565
2566/* Write out to F the table entry and any marker routines needed to
2567   mark NAME as TYPE.  The original variable is V, at LINE.
2568   HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
2569   is nonzero iff we are building the root table for hash table caches.  */
2570
2571static void
2572write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2573	    struct fileloc *line, const char *if_marked)
2574{
2575  switch (type->kind)
2576    {
2577    case TYPE_STRUCT:
2578      {
2579	pair_p fld;
2580	for (fld = type->u.s.fields; fld; fld = fld->next)
2581	  {
2582	    int skip_p = 0;
2583	    const char *desc = NULL;
2584	    options_p o;
2585
2586	    for (o = fld->opt; o; o = o->next)
2587	      if (strcmp (o->name, "skip") == 0)
2588		skip_p = 1;
2589	      else if (strcmp (o->name, "desc") == 0)
2590		desc = o->info;
2591	      else
2592		error_at_line (line,
2593		       "field `%s' of global `%s' has unknown option `%s'",
2594			       fld->name, name, o->name);
2595
2596	    if (skip_p)
2597	      continue;
2598	    else if (desc && fld->type->kind == TYPE_UNION)
2599	      {
2600		pair_p validf = NULL;
2601		pair_p ufld;
2602
2603		for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2604		  {
2605		    const char *tag = NULL;
2606		    options_p oo;
2607
2608		    for (oo = ufld->opt; oo; oo = oo->next)
2609		      if (strcmp (oo->name, "tag") == 0)
2610			tag = oo->info;
2611		    if (tag == NULL || strcmp (tag, desc) != 0)
2612		      continue;
2613		    if (validf != NULL)
2614		      error_at_line (line,
2615			   "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2616				     name, fld->name, validf->name,
2617				     name, fld->name, ufld->name,
2618				     tag);
2619		    validf = ufld;
2620		  }
2621		if (validf != NULL)
2622		  {
2623		    char *newname;
2624		    newname = xasprintf ("%s.%s.%s",
2625					 name, fld->name, validf->name);
2626		    write_root (f, v, validf->type, newname, 0, line,
2627				if_marked);
2628		    free (newname);
2629		  }
2630	      }
2631	    else if (desc)
2632	      error_at_line (line,
2633		     "global `%s.%s' has `desc' option but is not union",
2634			     name, fld->name);
2635	    else
2636	      {
2637		char *newname;
2638		newname = xasprintf ("%s.%s", name, fld->name);
2639		write_root (f, v, fld->type, newname, 0, line, if_marked);
2640		free (newname);
2641	      }
2642	  }
2643      }
2644      break;
2645
2646    case TYPE_ARRAY:
2647      {
2648	char *newname;
2649	newname = xasprintf ("%s[0]", name);
2650	write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2651	free (newname);
2652      }
2653      break;
2654
2655    case TYPE_POINTER:
2656      {
2657	type_p ap, tp;
2658
2659	oprintf (f, "  {\n");
2660	oprintf (f, "    &%s,\n", name);
2661	oprintf (f, "    1");
2662
2663	for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2664	  if (ap->u.a.len[0])
2665	    oprintf (f, " * (%s)", ap->u.a.len);
2666	  else if (ap == v->type)
2667	    oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2668	oprintf (f, ",\n");
2669	oprintf (f, "    sizeof (%s", v->name);
2670	for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2671	  oprintf (f, "[0]");
2672	oprintf (f, "),\n");
2673
2674	tp = type->u.p;
2675
2676	if (! has_length && UNION_OR_STRUCT_P (tp))
2677	  {
2678	    oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
2679	    oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
2680	  }
2681	else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2682	  {
2683	    oprintf (f, "    &gt_ggc_m_");
2684	    output_mangled_typename (f, tp);
2685	    oprintf (f, ",\n    &gt_pch_n_");
2686	    output_mangled_typename (f, tp);
2687	  }
2688	else if (has_length
2689		 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2690	  {
2691	    oprintf (f, "    &gt_ggc_ma_%s,\n", name);
2692	    oprintf (f, "    &gt_pch_na_%s", name);
2693	  }
2694	else
2695	  {
2696	    error_at_line (line,
2697			   "global `%s' is pointer to unimplemented type",
2698			   name);
2699	  }
2700	if (if_marked)
2701	  oprintf (f, ",\n    &%s", if_marked);
2702	oprintf (f, "\n  },\n");
2703      }
2704      break;
2705
2706    case TYPE_STRING:
2707      {
2708	oprintf (f, "  {\n");
2709	oprintf (f, "    &%s,\n", name);
2710	oprintf (f, "    1, \n");
2711	oprintf (f, "    sizeof (%s),\n", v->name);
2712	oprintf (f, "    &gt_ggc_m_S,\n");
2713	oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
2714	oprintf (f, "  },\n");
2715      }
2716      break;
2717
2718    case TYPE_SCALAR:
2719      break;
2720
2721    default:
2722      error_at_line (line,
2723		     "global `%s' is unimplemented type",
2724		     name);
2725    }
2726}
2727
2728/* This generates a routine to walk an array.  */
2729
2730static void
2731write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2732{
2733  struct walk_type_data d;
2734  char *prevval3;
2735
2736  memset (&d, 0, sizeof (d));
2737  d.of = f;
2738  d.cookie = wtd;
2739  d.indent = 2;
2740  d.line = &v->line;
2741  d.opt = v->opt;
2742  d.bitmap = get_base_file_bitmap (v->line.file);
2743  d.param = NULL;
2744
2745  d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2746
2747  if (wtd->param_prefix)
2748    {
2749      oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2750      oprintf (f,
2751       "    (void *, void *, gt_pointer_operator, void *);\n");
2752      oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2753	       wtd->param_prefix, v->name);
2754      oprintf (d.of,
2755	       "      ATTRIBUTE_UNUSED void *x_p,\n"
2756	       "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2757	       "      ATTRIBUTE_UNUSED void * cookie)\n");
2758      oprintf (d.of, "{\n");
2759      d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2760      d.process_field = write_types_local_process_field;
2761      walk_type (v->type, &d);
2762      oprintf (f, "}\n\n");
2763    }
2764
2765  d.opt = v->opt;
2766  oprintf (f, "static void gt_%sa_%s (void *);\n",
2767	   wtd->prefix, v->name);
2768  oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2769	   wtd->prefix, v->name);
2770  oprintf (f, "{\n");
2771  d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2772  d.process_field = write_types_process_field;
2773  walk_type (v->type, &d);
2774  free (prevval3);
2775  oprintf (f, "}\n\n");
2776}
2777
2778/* Output a table describing the locations and types of VARIABLES.  */
2779
2780static void
2781write_roots (pair_p variables)
2782{
2783  pair_p v;
2784  struct flist *flp = NULL;
2785
2786  for (v = variables; v; v = v->next)
2787    {
2788      outf_p f = get_output_file_with_visibility (v->line.file);
2789      struct flist *fli;
2790      const char *length = NULL;
2791      int deletable_p = 0;
2792      options_p o;
2793
2794      for (o = v->opt; o; o = o->next)
2795	if (strcmp (o->name, "length") == 0)
2796	  length = o->info;
2797	else if (strcmp (o->name, "deletable") == 0)
2798	  deletable_p = 1;
2799	else if (strcmp (o->name, "param_is") == 0)
2800	  ;
2801	else if (strncmp (o->name, "param", 5) == 0
2802		 && ISDIGIT (o->name[5])
2803		 && strcmp (o->name + 6, "_is") == 0)
2804	  ;
2805	else if (strcmp (o->name, "if_marked") == 0)
2806	  ;
2807	else
2808	  error_at_line (&v->line,
2809			 "global `%s' has unknown option `%s'",
2810			 v->name, o->name);
2811
2812      for (fli = flp; fli; fli = fli->next)
2813	if (fli->f == f)
2814	  break;
2815      if (fli == NULL)
2816	{
2817	  fli = XNEW (struct flist);
2818	  fli->f = f;
2819	  fli->next = flp;
2820	  fli->started_p = 0;
2821	  fli->name = v->line.file;
2822	  flp = fli;
2823
2824	  oprintf (f, "\n/* GC roots.  */\n\n");
2825	}
2826
2827      if (! deletable_p
2828	  && length
2829	  && v->type->kind == TYPE_POINTER
2830	  && (v->type->u.p->kind == TYPE_POINTER
2831	      || v->type->u.p->kind == TYPE_STRUCT))
2832	{
2833	  write_array (f, v, &ggc_wtd);
2834	  write_array (f, v, &pch_wtd);
2835	}
2836    }
2837
2838  for (v = variables; v; v = v->next)
2839    {
2840      outf_p f = get_output_file_with_visibility (v->line.file);
2841      struct flist *fli;
2842      int skip_p = 0;
2843      int length_p = 0;
2844      options_p o;
2845
2846      for (o = v->opt; o; o = o->next)
2847	if (strcmp (o->name, "length") == 0)
2848	  length_p = 1;
2849	else if (strcmp (o->name, "deletable") == 0
2850		 || strcmp (o->name, "if_marked") == 0)
2851	  skip_p = 1;
2852
2853      if (skip_p)
2854	continue;
2855
2856      for (fli = flp; fli; fli = fli->next)
2857	if (fli->f == f)
2858	  break;
2859      if (! fli->started_p)
2860	{
2861	  fli->started_p = 1;
2862
2863	  oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2864	  put_mangled_filename (f, v->line.file);
2865	  oprintf (f, "[] = {\n");
2866	}
2867
2868      write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2869    }
2870
2871  finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2872		     "gt_ggc_rtab");
2873
2874  for (v = variables; v; v = v->next)
2875    {
2876      outf_p f = get_output_file_with_visibility (v->line.file);
2877      struct flist *fli;
2878      int skip_p = 1;
2879      options_p o;
2880
2881      for (o = v->opt; o; o = o->next)
2882	if (strcmp (o->name, "deletable") == 0)
2883	  skip_p = 0;
2884	else if (strcmp (o->name, "if_marked") == 0)
2885	  skip_p = 1;
2886
2887      if (skip_p)
2888	continue;
2889
2890      for (fli = flp; fli; fli = fli->next)
2891	if (fli->f == f)
2892	  break;
2893      if (! fli->started_p)
2894	{
2895	  fli->started_p = 1;
2896
2897	  oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2898	  put_mangled_filename (f, v->line.file);
2899	  oprintf (f, "[] = {\n");
2900	}
2901
2902      oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
2903	       v->name, v->name);
2904    }
2905
2906  finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2907		     "gt_ggc_deletable_rtab");
2908
2909  for (v = variables; v; v = v->next)
2910    {
2911      outf_p f = get_output_file_with_visibility (v->line.file);
2912      struct flist *fli;
2913      const char *if_marked = NULL;
2914      int length_p = 0;
2915      options_p o;
2916
2917      for (o = v->opt; o; o = o->next)
2918	if (strcmp (o->name, "length") == 0)
2919	  length_p = 1;
2920	else if (strcmp (o->name, "if_marked") == 0)
2921	  if_marked = o->info;
2922
2923      if (if_marked == NULL)
2924	continue;
2925
2926      if (v->type->kind != TYPE_POINTER
2927	  || v->type->u.p->kind != TYPE_PARAM_STRUCT
2928	  || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2929	{
2930	  error_at_line (&v->line, "if_marked option used but not hash table");
2931	  continue;
2932	}
2933
2934      for (fli = flp; fli; fli = fli->next)
2935	if (fli->f == f)
2936	  break;
2937      if (! fli->started_p)
2938	{
2939	  fli->started_p = 1;
2940
2941	  oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2942	  put_mangled_filename (f, v->line.file);
2943	  oprintf (f, "[] = {\n");
2944	}
2945
2946      write_root (f, v, v->type->u.p->u.param_struct.param[0],
2947		     v->name, length_p, &v->line, if_marked);
2948    }
2949
2950  finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2951		     "gt_ggc_cache_rtab");
2952
2953  for (v = variables; v; v = v->next)
2954    {
2955      outf_p f = get_output_file_with_visibility (v->line.file);
2956      struct flist *fli;
2957      int length_p = 0;
2958      int if_marked_p = 0;
2959      options_p o;
2960
2961      for (o = v->opt; o; o = o->next)
2962	if (strcmp (o->name, "length") == 0)
2963	  length_p = 1;
2964	else if (strcmp (o->name, "if_marked") == 0)
2965	  if_marked_p = 1;
2966
2967      if (! if_marked_p)
2968	continue;
2969
2970      for (fli = flp; fli; fli = fli->next)
2971	if (fli->f == f)
2972	  break;
2973      if (! fli->started_p)
2974	{
2975	  fli->started_p = 1;
2976
2977	  oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2978	  put_mangled_filename (f, v->line.file);
2979	  oprintf (f, "[] = {\n");
2980	}
2981
2982      write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2983    }
2984
2985  finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2986		     "gt_pch_cache_rtab");
2987
2988  for (v = variables; v; v = v->next)
2989    {
2990      outf_p f = get_output_file_with_visibility (v->line.file);
2991      struct flist *fli;
2992      int skip_p = 0;
2993      options_p o;
2994
2995      for (o = v->opt; o; o = o->next)
2996	if (strcmp (o->name, "deletable") == 0
2997	    || strcmp (o->name, "if_marked") == 0)
2998	  skip_p = 1;
2999
3000      if (skip_p)
3001	continue;
3002
3003      if (! contains_scalar_p (v->type))
3004	continue;
3005
3006      for (fli = flp; fli; fli = fli->next)
3007	if (fli->f == f)
3008	  break;
3009      if (! fli->started_p)
3010	{
3011	  fli->started_p = 1;
3012
3013	  oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3014	  put_mangled_filename (f, v->line.file);
3015	  oprintf (f, "[] = {\n");
3016	}
3017
3018      oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3019	       v->name, v->name);
3020    }
3021
3022  finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3023		     "gt_pch_scalar_rtab");
3024}
3025
3026
3027extern int main (int argc, char **argv);
3028int
3029main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
3030{
3031  unsigned i;
3032  static struct fileloc pos = { __FILE__, __LINE__ };
3033  unsigned j;
3034
3035  gen_rtx_next ();
3036
3037  srcdir_len = strlen (srcdir);
3038
3039  do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3040  do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3041  do_scalar_typedef ("double_int", &pos);
3042  do_scalar_typedef ("uint8", &pos);
3043  do_scalar_typedef ("jword", &pos);
3044  do_scalar_typedef ("JCF_u2", &pos);
3045#ifdef USE_MAPPED_LOCATION
3046  do_scalar_typedef ("location_t", &pos);
3047  do_scalar_typedef ("source_locus", &pos);
3048#endif
3049  do_scalar_typedef ("void", &pos);
3050
3051  do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3052
3053  do_typedef ("HARD_REG_SET", create_array (
3054	      create_scalar_type ("unsigned long", strlen ("unsigned long")),
3055	      "2"), &pos);
3056
3057  for (i = 0; i < NUM_GT_FILES; i++)
3058    {
3059      int dupflag = 0;
3060      /* Omit if already seen.  */
3061      for (j = 0; j < i; j++)
3062        {
3063          if (!strcmp (all_files[i], all_files[j]))
3064            {
3065              dupflag = 1;
3066              break;
3067            }
3068        }
3069      if (!dupflag)
3070        parse_file (all_files[i]);
3071#ifndef USE_MAPPED_LOCATION
3072      /* temporary kludge - gengtype doesn't handle conditionals.
3073	 Manually add source_locus *after* we've processed input.h.  */
3074      if (i == 0)
3075	do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3076#endif
3077    }
3078
3079  if (hit_error != 0)
3080    exit (1);
3081
3082  set_gc_used (variables);
3083
3084  open_base_files ();
3085  write_enum_defn (structures, param_structs);
3086  write_types (structures, param_structs, &ggc_wtd);
3087  write_types (structures, param_structs, &pch_wtd);
3088  write_local (structures, param_structs);
3089  write_roots (variables);
3090  write_rtx_next ();
3091  close_output_files ();
3092
3093  return (hit_error != 0);
3094}
3095