xref: /openbsd/gnu/gcc/gcc/gengtype.c (revision 404b540a)
1 /* Process source files and output type information.
2    Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-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.  */
30 static int hit_error = 0;
31 
32 static void gen_rtx_next (void);
33 static void write_rtx_next (void);
34 static void open_base_files (void);
35 static void close_output_files (void);
36 
37 /* Report an error at POS, printing MSG.  */
38 
39 void
error_at_line(struct fileloc * pos,const char * msg,...)40 error_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.  */
55 int
xvasprintf(char ** result,const char * format,va_list args)56 xvasprintf (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.  */
68 char *
xasprintf(const char * format,...)69 xasprintf (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 
82 struct type string_type = {
83   TYPE_STRING, NULL, NULL, GC_USED, {0}
84 };
85 
86 /* Lists of various things.  */
87 
88 static pair_p typedefs;
89 static type_p structures;
90 static type_p param_structs;
91 static pair_p variables;
92 
93 static void do_scalar_typedef (const char *, struct fileloc *);
94 static type_p find_param_structure
95   (type_p t, type_p param[NUM_PARAM]);
96 static type_p adjust_field_tree_exp (type_p t, options_p opt);
97 static type_p adjust_field_rtx_def (type_p t, options_p opt);
98 
99 /* Define S as a typedef to T at POS.  */
100 
101 void
do_typedef(const char * s,type_p t,struct fileloc * pos)102 do_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 
127 static void
do_scalar_typedef(const char * s,struct fileloc * pos)128 do_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 
135 type_p
resolve_typedef(const char * s,struct fileloc * pos)136 resolve_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 
149 type_p
new_structure(const char * name,int isunion,struct fileloc * pos,pair_p fields,options_p o)150 new_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 
225 type_p
find_structure(const char * name,int isunion)226 find_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 
248 static type_p
find_param_structure(type_p t,type_p param[NUM_PARAM])249 find_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 
272 type_p
create_scalar_type(const char * name,size_t name_len)273 create_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 
283 type_p
create_pointer(type_p t)284 create_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 
298 type_p
create_array(type_p t,const char * len)299 create_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 
313 options_p
create_option(options_p next,const char * name,const void * info)314 create_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 
326 void
note_variable(const char * s,type_p t,options_p o,struct fileloc * pos)327 note_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 
342 static pair_p
create_field(pair_p next,type_p type,const char * name)343 create_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 
360 static pair_p
create_optional_field(pair_p next,type_p type,const char * name,const char * cond)361 create_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 
389 enum 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 
396 static 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 
402 static 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 
408 static 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.  */
412 enum 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.  */
422 static 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 
434 static void
gen_rtx_next(void)435 gen_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.  */
455 static void
write_rtx_next(void)456 write_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 
477 static type_p
adjust_field_rtx_def(type_p t,options_p ARG_UNUSED (opt))478 adjust_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 
705 static type_p
adjust_field_tree_exp(type_p t,options_p opt ATTRIBUTE_UNUSED)706 adjust_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 
738 type_p
adjust_field_type(type_p t,options_p opt)739 adjust_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 
817 void
note_yacc_type(options_p o,pair_p fields,pair_p typeinfo,struct fileloc * pos)818 note_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 
873 static void process_gc_options (options_p, enum gc_used_enum,
874 				int *, int *, int *, type_p *);
875 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
876 static void set_gc_used (pair_p);
877 
878 /* Handle OPT for set_gc_used_type.  */
879 
880 static void
process_gc_options(options_p opt,enum gc_used_enum level,int * maybe_undef,int * pass_param,int * length,type_p * nested_ptr)881 process_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 
900 static void
set_gc_used_type(type_p t,enum gc_used_enum level,type_p param[NUM_PARAM])901 set_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 
981 static void
set_gc_used(pair_p variables)982 set_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.  */
994 static outf_p output_files;
995 
996 /* The output header file that is included into pretty much every
997    source file.  */
998 static 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.  */
1007 static int srcdir_len = 0;
1008 
1009 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
1010 outf_p base_files[NUM_BASE_FILES];
1011 
1012 static outf_p create_file (const char *, const char *);
1013 static 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 
1018 static outf_p
create_file(const char * name,const char * oname)1019 create_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.  */
1058 void
oprintf(outf_p o,const char * format,...)1059 oprintf (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 
1087 static void
open_base_files(void)1088 open_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 
1121 static const char *
get_file_basename(const char * f)1122 get_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 
1164 unsigned
get_base_file_bitmap(const char * input_file)1165 get_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 
1217 outf_p
get_output_file_with_visibility(const char * input_file)1218 get_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 
1298 const char *
get_output_file_name(const char * input_file)1299 get_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 
1307 static void
close_output_files(void)1308 close_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 
1355 struct flist {
1356   struct flist *next;
1357   int started_p;
1358   const char *name;
1359   outf_p f;
1360 };
1361 
1362 struct 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 */
1368 typedef void (*process_field_fn)
1369      (type_p f, const struct walk_type_data *p);
1370 typedef void (*func_name_fn)
1371      (type_p s, const struct walk_type_data *p);
1372 
1373 /* Parameters for write_types.  */
1374 
1375 struct 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 
1385 static void output_escaped_param (struct walk_type_data *d,
1386 				  const char *, const char *);
1387 static void output_mangled_typename (outf_p, type_p);
1388 static void walk_type (type_p t, struct walk_type_data *d);
1389 static void write_func_for_structure
1390      (type_p orig_s, type_p s, type_p * param,
1391       const struct write_types_data *wtd);
1392 static void write_types_process_field
1393      (type_p f, const struct walk_type_data *d);
1394 static void write_types (type_p structures,
1395 			 type_p param_structs,
1396 			 const struct write_types_data *wtd);
1397 static void write_types_local_process_field
1398      (type_p f, const struct walk_type_data *d);
1399 static void write_local_func_for_structure
1400      (type_p orig_s, type_p s, type_p * param);
1401 static void write_local (type_p structures,
1402 			 type_p param_structs);
1403 static void write_enum_defn (type_p structures, type_p param_structs);
1404 static int contains_scalar_p (type_p t);
1405 static void put_mangled_filename (outf_p , const char *);
1406 static void finish_root_table (struct flist *flp, const char *pfx,
1407 			       const char *tname, const char *lastname,
1408 			       const char *name);
1409 static void write_root (outf_p , pair_p, type_p, const char *, int,
1410 			struct fileloc *, const char *);
1411 static void write_array (outf_p f, pair_p v,
1412 			 const struct write_types_data *wtd);
1413 static void write_roots (pair_p);
1414 
1415 /* Parameters for walk_type.  */
1416 
1417 struct 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 
1439 static void
output_mangled_typename(outf_p of,type_p t)1440 output_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 
1480 static void
output_escaped_param(struct walk_type_data * d,const char * param,const char * oname)1481 output_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 
1526 static void
walk_type(type_p t,struct walk_type_data * d)1527 walk_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 
1935 static void
write_types_process_field(type_p f,const struct walk_type_data * d)1936 write_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 
2007 static void
output_type_enum(outf_p of,type_p s)2008 output_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 
2032 static void
write_func_for_structure(type_p orig_s,type_p s,type_p * param,const struct write_types_data * wtd)2033 write_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 
2161 static void
write_types(type_p structures,type_p param_structs,const struct write_types_data * wtd)2162 write_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 
2256 static 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 
2262 static 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 
2273 static void
write_types_local_process_field(type_p f,const struct walk_type_data * d)2274 write_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 
2303 static void
write_local_func_for_structure(type_p orig_s,type_p s,type_p * param)2304 write_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 
2349 static void
write_local(type_p structures,type_p param_structs)2350 write_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 
2434 static void
write_enum_defn(type_p structures,type_p param_structs)2435 write_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 
2466 static int
contains_scalar_p(type_p t)2467 contains_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 
2485 static void
put_mangled_filename(outf_p f,const char * fn)2486 put_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 
2500 static void
finish_root_table(struct flist * flp,const char * pfx,const char * lastname,const char * tname,const char * name)2501 finish_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 
2571 static void
write_root(outf_p f,pair_p v,type_p type,const char * name,int has_length,struct fileloc * line,const char * if_marked)2572 write_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 
2730 static void
write_array(outf_p f,pair_p v,const struct write_types_data * wtd)2731 write_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 
2780 static void
write_roots(pair_p variables)2781 write_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 
3027 extern int main (int argc, char **argv);
3028 int
main(int ARG_UNUSED (argc),char ** ARG_UNUSED (argv))3029 main(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