Mercurial > hg > CbC > CbC_gcc
comparison gcc/gengtype.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Process source files and output type information. | 1 /* Process source files and output type information. |
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 | 2 Copyright (C) 2002-2017 Free Software Foundation, Inc. |
3 Free Software Foundation, Inc. | |
4 | 3 |
5 This file is part of GCC. | 4 This file is part of GCC. |
6 | 5 |
7 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
8 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
16 | 15 |
17 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
18 along with GCC; see the file COPYING3. If not see | 17 along with GCC; see the file COPYING3. If not see |
19 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
20 | 19 |
20 #ifdef HOST_GENERATOR_FILE | |
21 #include "config.h" | |
22 #define GENERATOR_FILE 1 | |
23 #else | |
21 #include "bconfig.h" | 24 #include "bconfig.h" |
25 #endif | |
22 #include "system.h" | 26 #include "system.h" |
23 #include "errors.h" /* for fatal */ | 27 #include "errors.h" /* for fatal */ |
24 #include "getopt.h" | 28 #include "getopt.h" |
25 #include "double-int.h" | |
26 #include "version.h" /* for version_string & pkgversion_string. */ | 29 #include "version.h" /* for version_string & pkgversion_string. */ |
27 #include "hashtab.h" | |
28 #include "xregex.h" | 30 #include "xregex.h" |
29 #include "obstack.h" | 31 #include "obstack.h" |
30 #include "gengtype.h" | 32 #include "gengtype.h" |
33 #include "filenames.h" | |
31 | 34 |
32 /* Data types, macros, etc. used only in this file. */ | 35 /* Data types, macros, etc. used only in this file. */ |
33 | 36 |
34 | 37 |
35 /* The list of output files. */ | 38 /* The list of output files. */ |
82 static const char *get_file_basename (const input_file *); | 85 static const char *get_file_basename (const input_file *); |
83 static const char *get_file_realbasename (const input_file *); | 86 static const char *get_file_realbasename (const input_file *); |
84 | 87 |
85 static int get_prefix_langdir_index (const char *); | 88 static int get_prefix_langdir_index (const char *); |
86 static const char *get_file_langdir (const input_file *); | 89 static const char *get_file_langdir (const input_file *); |
90 | |
91 static void dump_pair (int indent, pair_p p); | |
92 static void dump_type (int indent, type_p p); | |
93 static void dump_type_list (int indent, type_p p); | |
87 | 94 |
88 | 95 |
89 /* Nonzero iff an error has occurred. */ | 96 /* Nonzero iff an error has occurred. */ |
90 bool hit_error = false; | 97 bool hit_error = false; |
91 | 98 |
109 fputc ('\n', stderr); | 116 fputc ('\n', stderr); |
110 hit_error = true; | 117 hit_error = true; |
111 | 118 |
112 va_end (ap); | 119 va_end (ap); |
113 } | 120 } |
114 | 121 |
115 /* asprintf, but produces fatal message on out-of-memory. */ | 122 /* Locate the ultimate base class of struct S. */ |
116 char * | 123 |
117 xasprintf (const char *format, ...) | 124 static const_type_p |
118 { | 125 get_ultimate_base_class (const_type_p s) |
119 int n; | 126 { |
120 char *result; | 127 while (s->u.s.base_class) |
121 va_list ap; | 128 s = s->u.s.base_class; |
122 | 129 return s; |
123 va_start (ap, format); | 130 } |
124 n = vasprintf (&result, format, ap); | 131 |
125 if (result == NULL || n < 0) | 132 static type_p |
126 fatal ("out of memory"); | 133 get_ultimate_base_class (type_p s) |
127 va_end (ap); | 134 { |
128 | 135 while (s->u.s.base_class) |
129 return result; | 136 s = s->u.s.base_class; |
137 return s; | |
130 } | 138 } |
131 | 139 |
132 /* Input file handling. */ | 140 /* Input file handling. */ |
133 | 141 |
134 /* Table of all input files. */ | 142 /* Table of all input files. */ |
148 | 156 |
149 /* An array of output files suitable for definitions. There is one | 157 /* An array of output files suitable for definitions. There is one |
150 BASE_FILES entry for each language. */ | 158 BASE_FILES entry for each language. */ |
151 static outf_p *base_files; | 159 static outf_p *base_files; |
152 | 160 |
153 | |
154 | |
155 #if ENABLE_CHECKING | |
156 /* Utility debugging function, printing the various type counts within | 161 /* Utility debugging function, printing the various type counts within |
157 a list of types. Called thru the DBGPRINT_COUNT_TYPE macro. */ | 162 a list of types. Called through the DBGPRINT_COUNT_TYPE macro. */ |
158 void | 163 void |
159 dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t) | 164 dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t) |
160 { | 165 { |
161 int nb_types = 0, nb_scalar = 0, nb_string = 0; | 166 int nb_types = 0, nb_scalar = 0, nb_string = 0; |
162 int nb_struct = 0, nb_union = 0, nb_array = 0, nb_pointer = 0; | 167 int nb_struct = 0, nb_union = 0, nb_array = 0, nb_pointer = 0; |
163 int nb_lang_struct = 0, nb_param_struct = 0; | 168 int nb_lang_struct = 0; |
169 int nb_user_struct = 0, nb_undefined = 0; | |
164 type_p p = NULL; | 170 type_p p = NULL; |
165 for (p = t; p; p = p->next) | 171 for (p = t; p; p = p->next) |
166 { | 172 { |
167 nb_types++; | 173 nb_types++; |
168 switch (p->kind) | 174 switch (p->kind) |
169 { | 175 { |
176 case TYPE_UNDEFINED: | |
177 nb_undefined++; | |
178 break; | |
170 case TYPE_SCALAR: | 179 case TYPE_SCALAR: |
171 nb_scalar++; | 180 nb_scalar++; |
172 break; | 181 break; |
173 case TYPE_STRING: | 182 case TYPE_STRING: |
174 nb_string++; | 183 nb_string++; |
175 break; | 184 break; |
176 case TYPE_STRUCT: | 185 case TYPE_STRUCT: |
177 nb_struct++; | 186 nb_struct++; |
187 break; | |
188 case TYPE_USER_STRUCT: | |
189 nb_user_struct++; | |
178 break; | 190 break; |
179 case TYPE_UNION: | 191 case TYPE_UNION: |
180 nb_union++; | 192 nb_union++; |
181 break; | 193 break; |
182 case TYPE_POINTER: | 194 case TYPE_POINTER: |
186 nb_array++; | 198 nb_array++; |
187 break; | 199 break; |
188 case TYPE_LANG_STRUCT: | 200 case TYPE_LANG_STRUCT: |
189 nb_lang_struct++; | 201 nb_lang_struct++; |
190 break; | 202 break; |
191 case TYPE_PARAM_STRUCT: | 203 case TYPE_NONE: |
192 nb_param_struct++; | |
193 break; | |
194 default: | |
195 gcc_unreachable (); | 204 gcc_unreachable (); |
196 } | 205 } |
197 } | 206 } |
198 fprintf (stderr, "\n" "%s:%d: %s: @@%%@@ %d types ::\n", | 207 fprintf (stderr, "\n" "%s:%d: %s: @@%%@@ %d types ::\n", |
199 lbasename (fil), lin, msg, nb_types); | 208 lbasename (fil), lin, msg, nb_types); |
201 fprintf (stderr, "@@%%@@ %d scalars, %d strings\n", nb_scalar, nb_string); | 210 fprintf (stderr, "@@%%@@ %d scalars, %d strings\n", nb_scalar, nb_string); |
202 if (nb_struct > 0 || nb_union > 0) | 211 if (nb_struct > 0 || nb_union > 0) |
203 fprintf (stderr, "@@%%@@ %d structs, %d unions\n", nb_struct, nb_union); | 212 fprintf (stderr, "@@%%@@ %d structs, %d unions\n", nb_struct, nb_union); |
204 if (nb_pointer > 0 || nb_array > 0) | 213 if (nb_pointer > 0 || nb_array > 0) |
205 fprintf (stderr, "@@%%@@ %d pointers, %d arrays\n", nb_pointer, nb_array); | 214 fprintf (stderr, "@@%%@@ %d pointers, %d arrays\n", nb_pointer, nb_array); |
206 if (nb_lang_struct > 0 || nb_param_struct > 0) | 215 if (nb_lang_struct > 0) |
207 fprintf (stderr, "@@%%@@ %d lang_structs, %d param_structs\n", | 216 fprintf (stderr, "@@%%@@ %d lang_structs\n", nb_lang_struct); |
208 nb_lang_struct, nb_param_struct); | 217 if (nb_user_struct > 0) |
218 fprintf (stderr, "@@%%@@ %d user_structs\n", nb_user_struct); | |
219 if (nb_undefined > 0) | |
220 fprintf (stderr, "@@%%@@ %d undefined types\n", nb_undefined); | |
209 fprintf (stderr, "\n"); | 221 fprintf (stderr, "\n"); |
210 } | 222 } |
211 #endif /* ENABLE_CHECKING */ | |
212 | 223 |
213 /* Scan the input file, LIST, and determine how much space we need to | 224 /* Scan the input file, LIST, and determine how much space we need to |
214 store strings in. Also, count the number of language directories | 225 store strings in. Also, count the number of language directories |
215 and files. The numbers returned are overestimates as they does not | 226 and files. The numbers returned are overestimates as they does not |
216 consider repeated files. */ | 227 consider repeated files. */ |
427 for (f = 0; f < num_gt_files; f++) | 438 for (f = 0; f < num_gt_files; f++) |
428 { | 439 { |
429 lang_bitmap bitmap = get_lang_bitmap (gt_files[f]); | 440 lang_bitmap bitmap = get_lang_bitmap (gt_files[f]); |
430 const char *basename = get_file_basename (gt_files[f]); | 441 const char *basename = get_file_basename (gt_files[f]); |
431 const char *slashpos = strchr (basename, '/'); | 442 const char *slashpos = strchr (basename, '/'); |
443 #ifdef HAVE_DOS_BASED_FILE_SYSTEM | |
444 const char *slashpos2 = strchr (basename, '\\'); | |
445 | |
446 if (!slashpos || (slashpos2 && slashpos2 < slashpos)) | |
447 slashpos = slashpos2; | |
448 #endif | |
432 | 449 |
433 if (slashpos) | 450 if (slashpos) |
434 { | 451 { |
435 size_t l; | 452 size_t l; |
436 for (l = 0; l < num_lang_dirs; l++) | 453 for (l = 0; l < num_lang_dirs; l++) |
473 TYPE_SCALAR, 0, 0, 0, GC_USED, {0} | 490 TYPE_SCALAR, 0, 0, 0, GC_USED, {0} |
474 }; | 491 }; |
475 | 492 |
476 /* Lists of various things. */ | 493 /* Lists of various things. */ |
477 | 494 |
478 pair_p typedefs; | 495 pair_p typedefs = NULL; |
479 type_p structures; | 496 type_p structures = NULL; |
480 type_p param_structs; | 497 pair_p variables = NULL; |
481 pair_p variables; | 498 |
482 | |
483 static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]); | |
484 static type_p adjust_field_tree_exp (type_p t, options_p opt); | 499 static type_p adjust_field_tree_exp (type_p t, options_p opt); |
485 static type_p adjust_field_rtx_def (type_p t, options_p opt); | 500 static type_p adjust_field_rtx_def (type_p t, options_p opt); |
486 | 501 |
487 /* Define S as a typedef to T at POS. */ | 502 /* Define S as a typedef to T at POS. */ |
488 | 503 |
499 return; | 514 return; |
500 | 515 |
501 for (p = typedefs; p != NULL; p = p->next) | 516 for (p = typedefs; p != NULL; p = p->next) |
502 if (strcmp (p->name, s) == 0) | 517 if (strcmp (p->name, s) == 0) |
503 { | 518 { |
504 if (p->type != t) | 519 if (p->type != t && strcmp (s, "result_type") != 0) |
505 { | 520 { |
506 error_at_line (pos, "type `%s' previously defined", s); | 521 error_at_line (pos, "type `%s' previously defined", s); |
507 error_at_line (&p->line, "previously defined here"); | 522 error_at_line (&p->line, "previously defined here"); |
508 } | 523 } |
509 return; | 524 return; |
526 do_scalar_typedef (const char *s, struct fileloc *pos) | 541 do_scalar_typedef (const char *s, struct fileloc *pos) |
527 { | 542 { |
528 do_typedef (s, &scalar_nonchar, pos); | 543 do_typedef (s, &scalar_nonchar, pos); |
529 } | 544 } |
530 | 545 |
531 /* Return the type previously defined for S. Use POS to report errors. */ | 546 /* Similar to strtok_r. */ |
547 | |
548 static char * | |
549 strtoken (char *str, const char *delim, char **next) | |
550 { | |
551 char *p; | |
552 | |
553 if (str == NULL) | |
554 str = *next; | |
555 | |
556 /* Skip the leading delimiters. */ | |
557 str += strspn (str, delim); | |
558 if (*str == '\0') | |
559 /* This is an empty token. */ | |
560 return NULL; | |
561 | |
562 /* The current token. */ | |
563 p = str; | |
564 | |
565 /* Find the next delimiter. */ | |
566 str += strcspn (str, delim); | |
567 if (*str == '\0') | |
568 /* This is the last token. */ | |
569 *next = str; | |
570 else | |
571 { | |
572 /* Terminate the current token. */ | |
573 *str = '\0'; | |
574 /* Advance to the next token. */ | |
575 *next = str + 1; | |
576 } | |
577 | |
578 return p; | |
579 } | |
580 | |
581 /* Define TYPE_NAME to be a user defined type at location POS. */ | |
532 | 582 |
533 type_p | 583 type_p |
534 resolve_typedef (const char *s, struct fileloc *pos) | 584 create_user_defined_type (const char *type_name, struct fileloc *pos) |
585 { | |
586 type_p ty = find_structure (type_name, TYPE_USER_STRUCT); | |
587 | |
588 /* We might have already seen an incomplete decl of the given type, | |
589 in which case we won't have yet seen a GTY((user)), and the type will | |
590 only have kind "TYPE_STRUCT". Mark it as a user struct. */ | |
591 ty->kind = TYPE_USER_STRUCT; | |
592 | |
593 ty->u.s.line = *pos; | |
594 ty->u.s.bitmap = get_lang_bitmap (pos->file); | |
595 do_typedef (type_name, ty, pos); | |
596 | |
597 /* If TYPE_NAME specifies a template, create references to the types | |
598 in the template by pretending that each type is a field of TY. | |
599 This is needed to make sure that the types referenced by the | |
600 template are marked as used. */ | |
601 char *str = xstrdup (type_name); | |
602 char *open_bracket = strchr (str, '<'); | |
603 if (open_bracket) | |
604 { | |
605 /* We only accept simple template declarations (see | |
606 require_template_declaration), so we only need to parse a | |
607 comma-separated list of strings, implicitly assumed to | |
608 be type names, potentially with "*" characters. */ | |
609 char *arg = open_bracket + 1; | |
610 /* Workaround -Wmaybe-uninitialized false positive during | |
611 profiledbootstrap by initializing it. */ | |
612 char *next = NULL; | |
613 char *type_id = strtoken (arg, ",>", &next); | |
614 pair_p fields = 0; | |
615 while (type_id) | |
616 { | |
617 /* Create a new field for every type found inside the template | |
618 parameter list. */ | |
619 | |
620 /* Support a single trailing "*" character. */ | |
621 const char *star = strchr (type_id, '*'); | |
622 int is_ptr = (star != NULL); | |
623 size_t offset_to_star = star - type_id; | |
624 if (is_ptr) | |
625 offset_to_star = star - type_id; | |
626 | |
627 if (strstr (type_id, "char*")) | |
628 { | |
629 type_id = strtoken (0, ",>", &next); | |
630 continue; | |
631 } | |
632 | |
633 char *field_name = xstrdup (type_id); | |
634 | |
635 type_p arg_type; | |
636 if (is_ptr) | |
637 { | |
638 /* Strip off the first '*' character (and any subsequent text). */ | |
639 *(field_name + offset_to_star) = '\0'; | |
640 | |
641 arg_type = find_structure (field_name, TYPE_STRUCT); | |
642 arg_type = create_pointer (arg_type); | |
643 } | |
644 else | |
645 arg_type = resolve_typedef (field_name, pos); | |
646 | |
647 fields = create_field_at (fields, arg_type, field_name, 0, pos); | |
648 type_id = strtoken (0, ",>", &next); | |
649 } | |
650 | |
651 /* Associate the field list to TY. */ | |
652 ty->u.s.fields = fields; | |
653 } | |
654 free (str); | |
655 | |
656 return ty; | |
657 } | |
658 | |
659 | |
660 /* Given a typedef name S, return its associated type. Return NULL if | |
661 S is not a registered type name. */ | |
662 | |
663 static type_p | |
664 type_for_name (const char *s) | |
535 { | 665 { |
536 pair_p p; | 666 pair_p p; |
667 | |
668 /* Special-case support for types within a "gcc::" namespace. Rather | |
669 than fully-supporting namespaces, simply strip off the "gcc::" prefix | |
670 where present. This allows us to have GTY roots of this form: | |
671 extern GTY(()) gcc::some_type *some_ptr; | |
672 where the autogenerated functions will refer to simply "some_type", | |
673 where they can be resolved into their namespace. */ | |
674 if (0 == strncmp (s, "gcc::", 5)) | |
675 s += 5; | |
676 | |
537 for (p = typedefs; p != NULL; p = p->next) | 677 for (p = typedefs; p != NULL; p = p->next) |
538 if (strcmp (p->name, s) == 0) | 678 if (strcmp (p->name, s) == 0) |
539 return p->type; | 679 return p->type; |
540 error_at_line (pos, "unidentified type `%s'", s); | 680 return NULL; |
541 return &scalar_nonchar; /* treat as "int" */ | 681 } |
542 } | 682 |
543 | 683 |
544 /* Create and return a new structure with tag NAME (or a union iff | 684 /* Create an undefined type with name S and location POS. Return the |
545 ISUNION is nonzero), at POS with fields FIELDS and options O. */ | 685 newly created type. */ |
686 | |
687 static type_p | |
688 create_undefined_type (const char *s, struct fileloc *pos) | |
689 { | |
690 type_p ty = find_structure (s, TYPE_UNDEFINED); | |
691 ty->u.s.line = *pos; | |
692 ty->u.s.bitmap = get_lang_bitmap (pos->file); | |
693 do_typedef (s, ty, pos); | |
694 return ty; | |
695 } | |
696 | |
697 | |
698 /* Return the type previously defined for S. Use POS to report errors. */ | |
546 | 699 |
547 type_p | 700 type_p |
548 new_structure (const char *name, int isunion, struct fileloc *pos, | 701 resolve_typedef (const char *s, struct fileloc *pos) |
549 pair_p fields, options_p o) | 702 { |
703 bool is_template_instance = (strchr (s, '<') != NULL); | |
704 type_p p = type_for_name (s); | |
705 | |
706 /* If we did not find a typedef registered, generate a TYPE_UNDEFINED | |
707 type for regular type identifiers. If the type identifier S is a | |
708 template instantiation, however, we treat it as a user defined | |
709 type. | |
710 | |
711 FIXME, this is actually a limitation in gengtype. Supporting | |
712 template types and their instances would require keeping separate | |
713 track of the basic types definition and its instances. This | |
714 essentially forces all template classes in GC to be marked | |
715 GTY((user)). */ | |
716 if (!p) | |
717 p = (is_template_instance) | |
718 ? create_user_defined_type (s, pos) | |
719 : create_undefined_type (s, pos); | |
720 | |
721 return p; | |
722 } | |
723 | |
724 /* Add SUBCLASS to head of linked list of BASE's subclasses. */ | |
725 | |
726 void add_subclass (type_p base, type_p subclass) | |
727 { | |
728 gcc_assert (union_or_struct_p (base)); | |
729 gcc_assert (union_or_struct_p (subclass)); | |
730 | |
731 subclass->u.s.next_sibling_class = base->u.s.first_subclass; | |
732 base->u.s.first_subclass = subclass; | |
733 } | |
734 | |
735 /* Create and return a new structure with tag NAME at POS with fields | |
736 FIELDS and options O. The KIND of structure must be one of | |
737 TYPE_STRUCT, TYPE_UNION or TYPE_USER_STRUCT. */ | |
738 | |
739 type_p | |
740 new_structure (const char *name, enum typekind kind, struct fileloc *pos, | |
741 pair_p fields, options_p o, type_p base_class) | |
550 { | 742 { |
551 type_p si; | 743 type_p si; |
552 type_p s = NULL; | 744 type_p s = NULL; |
553 lang_bitmap bitmap = get_lang_bitmap (pos->file); | 745 lang_bitmap bitmap = get_lang_bitmap (pos->file); |
554 | 746 bool isunion = (kind == TYPE_UNION); |
555 for (si = structures; si != NULL; si = si->next) | 747 type_p *p = &structures; |
748 | |
749 gcc_assert (union_or_struct_p (kind)); | |
750 | |
751 for (si = structures; si != NULL; p = &si->next, si = *p) | |
556 if (strcmp (name, si->u.s.tag) == 0 && UNION_P (si) == isunion) | 752 if (strcmp (name, si->u.s.tag) == 0 && UNION_P (si) == isunion) |
557 { | 753 { |
558 type_p ls = NULL; | 754 type_p ls = NULL; |
559 if (si->kind == TYPE_LANG_STRUCT) | 755 if (si->kind == TYPE_LANG_STRUCT) |
560 { | 756 { |
596 if (s == NULL) | 792 if (s == NULL) |
597 { | 793 { |
598 type_count++; | 794 type_count++; |
599 s = XCNEW (struct type); | 795 s = XCNEW (struct type); |
600 s->state_number = -type_count; | 796 s->state_number = -type_count; |
601 s->next = structures; | 797 *p = s; |
602 structures = s; | 798 } |
603 } | 799 |
604 | 800 if (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)) |
605 if (s->u.s.line.file != NULL | |
606 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap))) | |
607 { | 801 { |
608 error_at_line (pos, "duplicate definition of '%s %s'", | 802 error_at_line (pos, "duplicate definition of '%s %s'", |
609 isunion ? "union" : "struct", s->u.s.tag); | 803 isunion ? "union" : "struct", s->u.s.tag); |
610 error_at_line (&s->u.s.line, "previous definition here"); | 804 error_at_line (&s->u.s.line, "previous definition here"); |
611 } | 805 } |
612 | 806 |
613 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT; | 807 s->kind = kind; |
614 s->u.s.tag = name; | 808 s->u.s.tag = name; |
615 s->u.s.line = *pos; | 809 s->u.s.line = *pos; |
616 s->u.s.fields = fields; | 810 s->u.s.fields = fields; |
617 s->u.s.opt = o; | 811 s->u.s.opt = o; |
618 s->u.s.bitmap = bitmap; | 812 s->u.s.bitmap = bitmap; |
619 if (s->u.s.lang_struct) | 813 if (s->u.s.lang_struct) |
620 s->u.s.lang_struct->u.s.bitmap |= bitmap; | 814 s->u.s.lang_struct->u.s.bitmap |= bitmap; |
815 s->u.s.base_class = base_class; | |
816 if (base_class) | |
817 add_subclass (base_class, s); | |
621 | 818 |
622 return s; | 819 return s; |
623 } | 820 } |
624 | 821 |
625 /* Return the previously-defined structure with tag NAME (or a union | 822 /* Return the previously-defined structure or union with tag NAME, |
626 iff ISUNION is nonzero), or a new empty structure or union if none | 823 or a new empty structure or union if none was defined previously. |
627 was defined previously. */ | 824 The KIND of structure must be one of TYPE_STRUCT, TYPE_UNION or |
825 TYPE_USER_STRUCT. */ | |
628 | 826 |
629 type_p | 827 type_p |
630 find_structure (const char *name, int isunion) | 828 find_structure (const char *name, enum typekind kind) |
631 { | 829 { |
632 type_p s; | 830 type_p s; |
633 | 831 bool isunion = (kind == TYPE_UNION); |
634 for (s = structures; s != NULL; s = s->next) | 832 type_p *p = &structures; |
833 | |
834 gcc_assert (kind == TYPE_UNDEFINED || union_or_struct_p (kind)); | |
835 | |
836 for (s = structures; s != NULL; p = &s->next, s = *p) | |
635 if (strcmp (name, s->u.s.tag) == 0 && UNION_P (s) == isunion) | 837 if (strcmp (name, s->u.s.tag) == 0 && UNION_P (s) == isunion) |
636 return s; | 838 return s; |
637 | 839 |
638 type_count++; | 840 type_count++; |
639 s = XCNEW (struct type); | 841 s = XCNEW (struct type); |
640 s->next = structures; | |
641 s->state_number = -type_count; | 842 s->state_number = -type_count; |
642 structures = s; | 843 s->kind = kind; |
643 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT; | |
644 s->u.s.tag = name; | 844 s->u.s.tag = name; |
645 structures = s; | 845 *p = s; |
646 return s; | 846 return s; |
647 } | |
648 | |
649 /* Return the previously-defined parameterized structure for structure | |
650 T and parameters PARAM, or a new parameterized empty structure or | |
651 union if none was defined previously. */ | |
652 | |
653 static type_p | |
654 find_param_structure (type_p t, type_p param[NUM_PARAM]) | |
655 { | |
656 type_p res; | |
657 | |
658 for (res = param_structs; res; res = res->next) | |
659 if (res->u.param_struct.stru == t | |
660 && memcmp (res->u.param_struct.param, param, | |
661 sizeof (type_p) * NUM_PARAM) == 0) | |
662 break; | |
663 if (res == NULL) | |
664 { | |
665 type_count++; | |
666 res = XCNEW (struct type); | |
667 res->kind = TYPE_PARAM_STRUCT; | |
668 res->next = param_structs; | |
669 res->state_number = -type_count; | |
670 param_structs = res; | |
671 res->u.param_struct.stru = t; | |
672 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM); | |
673 } | |
674 return res; | |
675 } | 847 } |
676 | 848 |
677 /* Return a scalar type with name NAME. */ | 849 /* Return a scalar type with name NAME. */ |
678 | 850 |
679 type_p | 851 type_p |
682 if (!strcmp (name, "char") || !strcmp (name, "unsigned char")) | 854 if (!strcmp (name, "char") || !strcmp (name, "unsigned char")) |
683 return &scalar_char; | 855 return &scalar_char; |
684 else | 856 else |
685 return &scalar_nonchar; | 857 return &scalar_nonchar; |
686 } | 858 } |
859 | |
687 | 860 |
688 /* Return a pointer to T. */ | 861 /* Return a pointer to T. */ |
689 | 862 |
690 type_p | 863 type_p |
691 create_pointer (type_p t) | 864 create_pointer (type_p t) |
816 } | 989 } |
817 | 990 |
818 /* Create a fake field with the given type and name. NEXT is the next | 991 /* Create a fake field with the given type and name. NEXT is the next |
819 field in the chain. */ | 992 field in the chain. */ |
820 #define create_field(next,type,name) \ | 993 #define create_field(next,type,name) \ |
821 create_field_all(next,type,name, 0, this_file, __LINE__) | 994 create_field_all (next,type,name, 0, this_file, __LINE__) |
822 | 995 |
823 /* Like create_field, but the field is only valid when condition COND | 996 /* Like create_field, but the field is only valid when condition COND |
824 is true. */ | 997 is true. */ |
825 | 998 |
826 static pair_p | 999 static pair_p |
838 union_fields->opt = | 1011 union_fields->opt = |
839 create_string_option (union_fields->opt, "dot", ""); | 1012 create_string_option (union_fields->opt, "dot", ""); |
840 union_fields->opt = | 1013 union_fields->opt = |
841 create_string_option (union_fields->opt, "tag", "1"); | 1014 create_string_option (union_fields->opt, "tag", "1"); |
842 union_type = | 1015 union_type = |
843 new_structure (xasprintf ("%s_%d", "fake_union", id++), 1, | 1016 new_structure (xasprintf ("%s_%d", "fake_union", id++), TYPE_UNION, |
844 &lexer_line, union_fields, NULL); | 1017 &lexer_line, union_fields, NULL, NULL); |
845 | 1018 |
846 /* Create the field and give it the new fake union type. Add a "desc" | 1019 /* Create the field and give it the new fake union type. Add a "desc" |
847 tag that specifies the condition under which the field is valid. */ | 1020 tag that specifies the condition under which the field is valid. */ |
848 return create_field_all (next, union_type, name, | 1021 return create_field_all (next, union_type, name, |
849 create_string_option (0, "desc", cond), | 1022 create_string_option (0, "desc", cond), |
927 for (i = 0; i < NUM_RTX_CODE; i++) | 1100 for (i = 0; i < NUM_RTX_CODE; i++) |
928 { | 1101 { |
929 int k; | 1102 int k; |
930 | 1103 |
931 rtx_next_new[i] = -1; | 1104 rtx_next_new[i] = -1; |
932 if (strncmp (rtx_format[i], "iuu", 3) == 0) | 1105 if (strncmp (rtx_format[i], "uu", 2) == 0) |
933 rtx_next_new[i] = 2; | 1106 rtx_next_new[i] = 1; |
934 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST) | 1107 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST) |
935 rtx_next_new[i] = 1; | 1108 rtx_next_new[i] = 1; |
936 else | 1109 else |
937 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--) | 1110 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--) |
938 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u') | 1111 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u') |
980 return &string_type; | 1153 return &string_type; |
981 } | 1154 } |
982 | 1155 |
983 nodot = create_string_option (NULL, "dot", ""); | 1156 nodot = create_string_option (NULL, "dot", ""); |
984 | 1157 |
985 rtx_tp = create_pointer (find_structure ("rtx_def", 0)); | 1158 rtx_tp = create_pointer (find_structure ("rtx_def", TYPE_STRUCT)); |
986 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0)); | 1159 rtvec_tp = create_pointer (find_structure ("rtvec_def", TYPE_STRUCT)); |
987 tree_tp = create_pointer (find_structure ("tree_node", 1)); | 1160 tree_tp = create_pointer (find_structure ("tree_node", TYPE_UNION)); |
988 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0)); | 1161 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", TYPE_STRUCT)); |
989 reg_attrs_tp = | 1162 reg_attrs_tp = |
990 create_pointer (find_structure ("reg_attrs", 0)); | 1163 create_pointer (find_structure ("reg_attrs", TYPE_STRUCT)); |
991 basic_block_tp = | 1164 basic_block_tp = |
992 create_pointer (find_structure ("basic_block_def", 0)); | 1165 create_pointer (find_structure ("basic_block_def", TYPE_STRUCT)); |
993 constant_tp = | 1166 constant_tp = |
994 create_pointer (find_structure ("constant_descriptor_rtx", 0)); | 1167 create_pointer (find_structure ("constant_descriptor_rtx", TYPE_STRUCT)); |
995 scalar_tp = &scalar_nonchar; /* rtunion int */ | 1168 scalar_tp = &scalar_nonchar; /* rtunion int */ |
996 | 1169 |
997 { | 1170 { |
998 pair_p note_flds = NULL; | 1171 pair_p note_flds = NULL; |
999 int c; | 1172 int c; |
1002 { | 1175 { |
1003 switch (c) | 1176 switch (c) |
1004 { | 1177 { |
1005 case NOTE_INSN_MAX: | 1178 case NOTE_INSN_MAX: |
1006 case NOTE_INSN_DELETED_LABEL: | 1179 case NOTE_INSN_DELETED_LABEL: |
1180 case NOTE_INSN_DELETED_DEBUG_LABEL: | |
1007 note_flds = create_field (note_flds, &string_type, "rt_str"); | 1181 note_flds = create_field (note_flds, &string_type, "rt_str"); |
1008 break; | 1182 break; |
1009 | 1183 |
1010 case NOTE_INSN_BLOCK_BEG: | 1184 case NOTE_INSN_BLOCK_BEG: |
1011 case NOTE_INSN_BLOCK_END: | 1185 case NOTE_INSN_BLOCK_END: |
1012 note_flds = create_field (note_flds, tree_tp, "rt_tree"); | 1186 note_flds = create_field (note_flds, tree_tp, "rt_tree"); |
1013 break; | 1187 break; |
1014 | 1188 |
1015 case NOTE_INSN_VAR_LOCATION: | 1189 case NOTE_INSN_VAR_LOCATION: |
1190 case NOTE_INSN_CALL_ARG_LOCATION: | |
1016 note_flds = create_field (note_flds, rtx_tp, "rt_rtx"); | 1191 note_flds = create_field (note_flds, rtx_tp, "rt_rtx"); |
1017 break; | 1192 break; |
1018 | 1193 |
1019 default: | 1194 default: |
1020 note_flds = create_field (note_flds, scalar_tp, "rt_int"); | 1195 note_flds = create_field (note_flds, scalar_tp, "rt_int"); |
1027 create_string_option (nodot, "default", ""); | 1202 create_string_option (nodot, "default", ""); |
1028 else | 1203 else |
1029 note_flds->opt = | 1204 note_flds->opt = |
1030 create_string_option (nodot, "tag", note_insn_name[c]); | 1205 create_string_option (nodot, "tag", note_insn_name[c]); |
1031 } | 1206 } |
1032 note_union_tp = new_structure ("rtx_def_note_subunion", 1, | 1207 note_union_tp = new_structure ("rtx_def_note_subunion", TYPE_UNION, |
1033 &lexer_line, note_flds, NULL); | 1208 &lexer_line, note_flds, NULL, NULL); |
1034 } | 1209 } |
1035 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */ | 1210 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */ |
1036 { | 1211 { |
1037 pair_p sym_flds; | 1212 pair_p sym_flds; |
1038 sym_flds = create_field (NULL, tree_tp, "rt_tree"); | 1213 sym_flds = create_field (NULL, tree_tp, "rt_tree"); |
1039 sym_flds->opt = create_string_option (nodot, "default", ""); | 1214 sym_flds->opt = create_string_option (nodot, "default", ""); |
1040 sym_flds = create_field (sym_flds, constant_tp, "rt_constant"); | 1215 sym_flds = create_field (sym_flds, constant_tp, "rt_constant"); |
1041 sym_flds->opt = create_string_option (nodot, "tag", "1"); | 1216 sym_flds->opt = create_string_option (nodot, "tag", "1"); |
1042 symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1, | 1217 symbol_union_tp = new_structure ("rtx_def_symbol_subunion", TYPE_UNION, |
1043 &lexer_line, sym_flds, NULL); | 1218 &lexer_line, sym_flds, NULL, NULL); |
1044 } | 1219 } |
1045 for (i = 0; i < NUM_RTX_CODE; i++) | 1220 for (i = 0; i < NUM_RTX_CODE; i++) |
1046 { | 1221 { |
1047 pair_p subfields = NULL; | 1222 pair_p subfields = NULL; |
1048 size_t aindex, nmindex; | 1223 size_t aindex, nmindex; |
1059 { | 1234 { |
1060 case '*': | 1235 case '*': |
1061 case 'i': | 1236 case 'i': |
1062 case 'n': | 1237 case 'n': |
1063 case 'w': | 1238 case 'w': |
1239 case 'r': | |
1064 t = scalar_tp; | 1240 t = scalar_tp; |
1065 subname = "rt_int"; | 1241 subname = "rt_int"; |
1066 break; | 1242 break; |
1067 | 1243 |
1068 case '0': | 1244 case '0': |
1069 if (i == MEM && aindex == 1) | 1245 if (i == MEM && aindex == 1) |
1070 t = mem_attrs_tp, subname = "rt_mem"; | 1246 t = mem_attrs_tp, subname = "rt_mem"; |
1071 else if (i == JUMP_INSN && aindex == 8) | 1247 else if (i == JUMP_INSN && aindex == 7) |
1072 t = rtx_tp, subname = "rt_rtx"; | 1248 t = rtx_tp, subname = "rt_rtx"; |
1073 else if (i == CODE_LABEL && aindex == 5) | 1249 else if (i == CODE_LABEL && aindex == 4) |
1074 t = scalar_tp, subname = "rt_int"; | 1250 t = scalar_tp, subname = "rt_int"; |
1075 else if (i == CODE_LABEL && aindex == 4) | 1251 else if (i == CODE_LABEL && aindex == 3) |
1076 t = rtx_tp, subname = "rt_rtx"; | 1252 t = rtx_tp, subname = "rt_rtx"; |
1077 else if (i == LABEL_REF && (aindex == 1 || aindex == 2)) | 1253 else if (i == LABEL_REF && (aindex == 1 || aindex == 2)) |
1078 t = rtx_tp, subname = "rt_rtx"; | 1254 t = rtx_tp, subname = "rt_rtx"; |
1255 else if (i == NOTE && aindex == 3) | |
1256 t = note_union_tp, subname = ""; | |
1079 else if (i == NOTE && aindex == 4) | 1257 else if (i == NOTE && aindex == 4) |
1080 t = note_union_tp, subname = ""; | |
1081 else if (i == NOTE && aindex == 5) | |
1082 t = scalar_tp, subname = "rt_int"; | 1258 t = scalar_tp, subname = "rt_int"; |
1083 else if (i == NOTE && aindex >= 7) | 1259 else if (i == NOTE && aindex >= 6) |
1084 t = scalar_tp, subname = "rt_int"; | 1260 t = scalar_tp, subname = "rt_int"; |
1085 else if (i == ADDR_DIFF_VEC && aindex == 4) | 1261 else if (i == ADDR_DIFF_VEC && aindex == 4) |
1086 t = scalar_tp, subname = "rt_int"; | 1262 t = scalar_tp, subname = "rt_int"; |
1087 else if (i == VALUE && aindex == 0) | 1263 else if (i == VALUE && aindex == 0) |
1088 t = scalar_tp, subname = "rt_int"; | 1264 t = scalar_tp, subname = "rt_int"; |
1089 else if (i == DEBUG_EXPR && aindex == 0) | 1265 else if (i == DEBUG_EXPR && aindex == 0) |
1090 t = tree_tp, subname = "rt_tree"; | 1266 t = tree_tp, subname = "rt_tree"; |
1091 else if (i == REG && aindex == 1) | 1267 else if (i == SYMBOL_REF && aindex == 1) |
1268 t = symbol_union_tp, subname = ""; | |
1269 else if (i == JUMP_TABLE_DATA && aindex >= 4) | |
1092 t = scalar_tp, subname = "rt_int"; | 1270 t = scalar_tp, subname = "rt_int"; |
1093 else if (i == REG && aindex == 2) | 1271 else if (i == BARRIER && aindex >= 2) |
1094 t = reg_attrs_tp, subname = "rt_reg"; | |
1095 else if (i == SCRATCH && aindex == 0) | |
1096 t = scalar_tp, subname = "rt_int"; | 1272 t = scalar_tp, subname = "rt_int"; |
1097 else if (i == SYMBOL_REF && aindex == 1) | 1273 else if (i == ENTRY_VALUE && aindex == 0) |
1098 t = scalar_tp, subname = "rt_int"; | 1274 t = rtx_tp, subname = "rt_rtx"; |
1099 else if (i == SYMBOL_REF && aindex == 2) | |
1100 t = symbol_union_tp, subname = ""; | |
1101 else if (i == BARRIER && aindex >= 3) | |
1102 t = scalar_tp, subname = "rt_int"; | |
1103 else | 1275 else |
1104 { | 1276 { |
1105 error_at_line | 1277 error_at_line |
1106 (&lexer_line, | 1278 (&lexer_line, |
1107 "rtx type `%s' has `0' in position %lu, can't handle", | 1279 "rtx type `%s' has `0' in position %lu, can't handle", |
1164 subfields->opt = | 1336 subfields->opt = |
1165 create_string_option (subfields->opt, "desc", | 1337 create_string_option (subfields->opt, "desc", |
1166 "CONSTANT_POOL_ADDRESS_P (&%0)"); | 1338 "CONSTANT_POOL_ADDRESS_P (&%0)"); |
1167 } | 1339 } |
1168 | 1340 |
1341 if (i == REG) | |
1342 subfields = create_field (subfields, reg_attrs_tp, "reg.attrs"); | |
1343 | |
1169 if (i == SYMBOL_REF) | 1344 if (i == SYMBOL_REF) |
1170 { | 1345 { |
1171 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P | 1346 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P |
1172 holds. */ | 1347 holds. */ |
1173 type_p field_tp = find_structure ("block_symbol", 0); | 1348 type_p field_tp = find_structure ("block_symbol", TYPE_STRUCT); |
1174 subfields | 1349 subfields |
1175 = create_optional_field (subfields, field_tp, "block_sym", | 1350 = create_optional_field (subfields, field_tp, "block_sym", |
1176 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)"); | 1351 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)"); |
1177 } | 1352 } |
1178 | 1353 |
1179 sname = xasprintf ("rtx_def_%s", rtx_name[i]); | 1354 sname = xasprintf ("rtx_def_%s", rtx_name[i]); |
1180 substruct = new_structure (sname, 0, &lexer_line, subfields, NULL); | 1355 substruct = new_structure (sname, TYPE_STRUCT, &lexer_line, subfields, |
1356 NULL, NULL); | |
1181 | 1357 |
1182 ftag = xstrdup (rtx_name[i]); | 1358 ftag = xstrdup (rtx_name[i]); |
1183 for (nmindex = 0; nmindex < strlen (ftag); nmindex++) | 1359 for (nmindex = 0; nmindex < strlen (ftag); nmindex++) |
1184 ftag[nmindex] = TOUPPER (ftag[nmindex]); | 1360 ftag[nmindex] = TOUPPER (ftag[nmindex]); |
1185 flds = create_field (flds, substruct, ""); | 1361 flds = create_field (flds, substruct, ""); |
1186 flds->opt = create_string_option (nodot, "tag", ftag); | 1362 flds->opt = create_string_option (nodot, "tag", ftag); |
1187 } | 1363 } |
1188 return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot); | 1364 return new_structure ("rtx_def_subunion", TYPE_UNION, &lexer_line, flds, |
1365 nodot, NULL); | |
1189 } | 1366 } |
1190 | 1367 |
1191 /* Handle `special("tree_exp")'. This is a special case for | 1368 /* Handle `special("tree_exp")'. This is a special case for |
1192 field `operands' of struct tree_exp, which although it claims to contain | 1369 field `operands' of struct tree_exp, which although it claims to contain |
1193 pointers to trees, actually sometimes contains pointers to RTL too. | 1370 pointers to trees, actually sometimes contains pointers to RTL too. |
1212 flds = create_field (NULL, t, ""); | 1389 flds = create_field (NULL, t, ""); |
1213 flds->opt = create_string_option (nodot, "length", | 1390 flds->opt = create_string_option (nodot, "length", |
1214 "TREE_OPERAND_LENGTH ((tree) &%0)"); | 1391 "TREE_OPERAND_LENGTH ((tree) &%0)"); |
1215 flds->opt = create_string_option (flds->opt, "default", ""); | 1392 flds->opt = create_string_option (flds->opt, "default", ""); |
1216 | 1393 |
1217 return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot); | 1394 return new_structure ("tree_exp_subunion", TYPE_UNION, &lexer_line, flds, |
1395 nodot, NULL); | |
1218 } | 1396 } |
1219 | 1397 |
1220 /* Perform any special processing on a type T, about to become the type | 1398 /* Perform any special processing on a type T, about to become the type |
1221 of a field. Return the appropriate type for the field. | 1399 of a field. Return the appropriate type for the field. |
1222 At present: | 1400 At present: |
1230 type_p | 1408 type_p |
1231 adjust_field_type (type_p t, options_p opt) | 1409 adjust_field_type (type_p t, options_p opt) |
1232 { | 1410 { |
1233 int length_p = 0; | 1411 int length_p = 0; |
1234 const int pointer_p = t->kind == TYPE_POINTER; | 1412 const int pointer_p = t->kind == TYPE_POINTER; |
1235 type_p params[NUM_PARAM]; | |
1236 int params_p = 0; | |
1237 int i; | |
1238 | |
1239 for (i = 0; i < NUM_PARAM; i++) | |
1240 params[i] = NULL; | |
1241 | 1413 |
1242 for (; opt; opt = opt->next) | 1414 for (; opt; opt = opt->next) |
1243 if (strcmp (opt->name, "length") == 0) | 1415 if (strcmp (opt->name, "length") == 0) |
1244 length_p = 1; | |
1245 else if ((strcmp (opt->name, "param_is") == 0 | |
1246 || (strncmp (opt->name, "param", 5) == 0 | |
1247 && ISDIGIT (opt->name[5]) | |
1248 && strcmp (opt->name + 6, "_is") == 0)) | |
1249 && opt->kind == OPTION_TYPE) | |
1250 { | 1416 { |
1251 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0; | 1417 if (length_p) |
1252 | 1418 error_at_line (&lexer_line, "duplicate `%s' option", opt->name); |
1253 if (!UNION_OR_STRUCT_P (t) | 1419 if (t->u.p->kind == TYPE_SCALAR || t->u.p->kind == TYPE_STRING) |
1254 && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p))) | |
1255 { | 1420 { |
1256 error_at_line (&lexer_line, | 1421 error_at_line (&lexer_line, |
1257 "option `%s' may only be applied to structures or structure pointers", | 1422 "option `%s' may not be applied to " |
1258 opt->name); | 1423 "arrays of atomic types", opt->name); |
1259 return t; | |
1260 } | 1424 } |
1261 | 1425 length_p = 1; |
1262 params_p = 1; | |
1263 if (params[num] != NULL) | |
1264 error_at_line (&lexer_line, "duplicate `%s' option", opt->name); | |
1265 if (!ISDIGIT (opt->name[5])) | |
1266 params[num] = create_pointer (opt->info.type); | |
1267 else | |
1268 params[num] = opt->info.type; | |
1269 } | 1426 } |
1270 else if (strcmp (opt->name, "special") == 0 | 1427 else if (strcmp (opt->name, "special") == 0 |
1271 && opt->kind == OPTION_STRING) | 1428 && opt->kind == OPTION_STRING) |
1272 { | 1429 { |
1273 const char *special_name = opt->info.string; | 1430 const char *special_name = opt->info.string; |
1277 t = adjust_field_rtx_def (t, opt); | 1434 t = adjust_field_rtx_def (t, opt); |
1278 else | 1435 else |
1279 error_at_line (&lexer_line, "unknown special `%s'", special_name); | 1436 error_at_line (&lexer_line, "unknown special `%s'", special_name); |
1280 } | 1437 } |
1281 | 1438 |
1282 if (params_p) | |
1283 { | |
1284 type_p realt; | |
1285 | |
1286 if (pointer_p) | |
1287 t = t->u.p; | |
1288 realt = find_param_structure (t, params); | |
1289 t = pointer_p ? create_pointer (realt) : realt; | |
1290 } | |
1291 | |
1292 if (!length_p | 1439 if (!length_p |
1293 && pointer_p && t->u.p->kind == TYPE_SCALAR && t->u.p->u.scalar_is_char) | 1440 && pointer_p && t->u.p->kind == TYPE_SCALAR && t->u.p->u.scalar_is_char) |
1294 return &string_type; | 1441 return &string_type; |
1295 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER | 1442 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER |
1296 && t->u.a.p->u.p->kind == TYPE_SCALAR | 1443 && t->u.a.p->u.p->kind == TYPE_SCALAR |
1299 | 1446 |
1300 return t; | 1447 return t; |
1301 } | 1448 } |
1302 | 1449 |
1303 | 1450 |
1304 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *); | 1451 static void set_gc_used_type (type_p, enum gc_used_enum, bool = false); |
1305 static void set_gc_used (pair_p); | 1452 static void set_gc_used (pair_p); |
1306 | 1453 |
1307 /* Handle OPT for set_gc_used_type. */ | 1454 /* Handle OPT for set_gc_used_type. */ |
1308 | 1455 |
1309 static void | 1456 static void |
1310 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef, | 1457 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef, |
1311 int *pass_param, int *length, int *skip, | 1458 int *length, int *skip, type_p *nested_ptr) |
1312 type_p *nested_ptr) | |
1313 { | 1459 { |
1314 options_p o; | 1460 options_p o; |
1315 for (o = opt; o; o = o->next) | 1461 for (o = opt; o; o = o->next) |
1316 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO | 1462 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO |
1317 && o->kind == OPTION_TYPE) | 1463 && o->kind == OPTION_TYPE) |
1318 set_gc_used_type (o->info.type, | 1464 set_gc_used_type (o->info.type, |
1319 GC_POINTED_TO, NULL); | 1465 GC_POINTED_TO); |
1320 else if (strcmp (o->name, "maybe_undef") == 0) | 1466 else if (strcmp (o->name, "maybe_undef") == 0) |
1321 *maybe_undef = 1; | 1467 *maybe_undef = 1; |
1322 else if (strcmp (o->name, "use_params") == 0) | |
1323 *pass_param = 1; | |
1324 else if (strcmp (o->name, "length") == 0) | 1468 else if (strcmp (o->name, "length") == 0) |
1325 *length = 1; | 1469 *length = 1; |
1326 else if (strcmp (o->name, "skip") == 0) | 1470 else if (strcmp (o->name, "skip") == 0) |
1327 *skip = 1; | 1471 *skip = 1; |
1328 else if (strcmp (o->name, "nested_ptr") == 0 | 1472 else if (strcmp (o->name, "nested_ptr") == 0 |
1329 && o->kind == OPTION_NESTED) | 1473 && o->kind == OPTION_NESTED) |
1330 *nested_ptr = ((const struct nested_ptr_data *) o->info.nested)->type; | 1474 *nested_ptr = ((const struct nested_ptr_data *) o->info.nested)->type; |
1331 } | 1475 } |
1332 | 1476 |
1333 | 1477 |
1334 /* Set the gc_used field of T to LEVEL, and handle the types it references. */ | 1478 /* Set the gc_used field of T to LEVEL, and handle the types it references. |
1479 | |
1480 If ALLOWED_UNDEFINED_TYPES is true, types of kind TYPE_UNDEFINED | |
1481 are set to GC_UNUSED. Otherwise, an error is emitted for | |
1482 TYPE_UNDEFINED types. This is used to support user-defined | |
1483 template types with non-type arguments. | |
1484 | |
1485 For instance, when we parse a template type with enum arguments | |
1486 (e.g. MyType<AnotherType, EnumValue>), the parser created two | |
1487 artificial fields for 'MyType', one for 'AnotherType', the other | |
1488 one for 'EnumValue'. | |
1489 | |
1490 At the time that we parse this type we don't know that 'EnumValue' | |
1491 is really an enum value, so the parser creates a TYPE_UNDEFINED | |
1492 type for it. Since 'EnumValue' is never resolved to a known | |
1493 structure, it will stay with TYPE_UNDEFINED. | |
1494 | |
1495 Since 'MyType' is a TYPE_USER_STRUCT, we can simply ignore | |
1496 'EnumValue'. Generating marking code for it would cause | |
1497 compilation failures since the marking routines assumes that | |
1498 'EnumValue' is a type. */ | |
1499 | |
1335 static void | 1500 static void |
1336 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM]) | 1501 set_gc_used_type (type_p t, enum gc_used_enum level, |
1502 bool allow_undefined_types) | |
1337 { | 1503 { |
1338 if (t->gc_used >= level) | 1504 if (t->gc_used >= level) |
1339 return; | 1505 return; |
1340 | 1506 |
1341 t->gc_used = level; | 1507 t->gc_used = level; |
1342 | 1508 |
1343 switch (t->kind) | 1509 switch (t->kind) |
1344 { | 1510 { |
1345 case TYPE_STRUCT: | 1511 case TYPE_STRUCT: |
1346 case TYPE_UNION: | 1512 case TYPE_UNION: |
1513 case TYPE_USER_STRUCT: | |
1347 { | 1514 { |
1348 pair_p f; | 1515 pair_p f; |
1349 int dummy; | 1516 int dummy; |
1350 type_p dummy2; | 1517 type_p dummy2; |
1351 | 1518 bool allow_undefined_field_types = (t->kind == TYPE_USER_STRUCT); |
1352 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy, | 1519 |
1520 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, | |
1353 &dummy2); | 1521 &dummy2); |
1354 | 1522 |
1355 for (f = t->u.s.fields; f; f = f->next) | 1523 if (t->u.s.base_class) |
1524 set_gc_used_type (t->u.s.base_class, level, allow_undefined_types); | |
1525 /* Anything pointing to a base class might actually be pointing | |
1526 to a subclass. */ | |
1527 for (type_p subclass = t->u.s.first_subclass; subclass; | |
1528 subclass = subclass->u.s.next_sibling_class) | |
1529 set_gc_used_type (subclass, level, allow_undefined_types); | |
1530 | |
1531 FOR_ALL_INHERITED_FIELDS(t, f) | |
1356 { | 1532 { |
1357 int maybe_undef = 0; | 1533 int maybe_undef = 0; |
1358 int pass_param = 0; | |
1359 int length = 0; | 1534 int length = 0; |
1360 int skip = 0; | 1535 int skip = 0; |
1361 type_p nested_ptr = NULL; | 1536 type_p nested_ptr = NULL; |
1362 process_gc_options (f->opt, level, &maybe_undef, &pass_param, | 1537 process_gc_options (f->opt, level, &maybe_undef, &length, &skip, |
1363 &length, &skip, &nested_ptr); | 1538 &nested_ptr); |
1364 | 1539 |
1365 if (nested_ptr && f->type->kind == TYPE_POINTER) | 1540 if (nested_ptr && f->type->kind == TYPE_POINTER) |
1366 set_gc_used_type (nested_ptr, GC_POINTED_TO, | 1541 set_gc_used_type (nested_ptr, GC_POINTED_TO); |
1367 pass_param ? param : NULL); | |
1368 else if (length && f->type->kind == TYPE_POINTER) | 1542 else if (length && f->type->kind == TYPE_POINTER) |
1369 set_gc_used_type (f->type->u.p, GC_USED, NULL); | 1543 set_gc_used_type (f->type->u.p, GC_USED); |
1370 else if (maybe_undef && f->type->kind == TYPE_POINTER) | 1544 else if (maybe_undef && f->type->kind == TYPE_POINTER) |
1371 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL); | 1545 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO); |
1372 else if (pass_param && f->type->kind == TYPE_POINTER && param) | |
1373 set_gc_used_type (find_param_structure (f->type->u.p, param), | |
1374 GC_POINTED_TO, NULL); | |
1375 else if (skip) | 1546 else if (skip) |
1376 ; /* target type is not used through this field */ | 1547 ; /* target type is not used through this field */ |
1377 else | 1548 else |
1378 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL); | 1549 set_gc_used_type (f->type, GC_USED, allow_undefined_field_types); |
1379 } | 1550 } |
1380 break; | 1551 break; |
1381 } | 1552 } |
1382 | 1553 |
1554 case TYPE_UNDEFINED: | |
1555 if (level > GC_UNUSED) | |
1556 { | |
1557 if (!allow_undefined_types) | |
1558 error_at_line (&t->u.s.line, "undefined type `%s'", t->u.s.tag); | |
1559 t->gc_used = GC_UNUSED; | |
1560 } | |
1561 break; | |
1562 | |
1383 case TYPE_POINTER: | 1563 case TYPE_POINTER: |
1384 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL); | 1564 set_gc_used_type (t->u.p, GC_POINTED_TO); |
1385 break; | 1565 break; |
1386 | 1566 |
1387 case TYPE_ARRAY: | 1567 case TYPE_ARRAY: |
1388 set_gc_used_type (t->u.a.p, GC_USED, param); | 1568 set_gc_used_type (t->u.a.p, GC_USED); |
1389 break; | 1569 break; |
1390 | 1570 |
1391 case TYPE_LANG_STRUCT: | 1571 case TYPE_LANG_STRUCT: |
1392 for (t = t->u.s.lang_struct; t; t = t->next) | 1572 for (t = t->u.s.lang_struct; t; t = t->next) |
1393 set_gc_used_type (t, level, param); | 1573 set_gc_used_type (t, level); |
1394 break; | |
1395 | |
1396 case TYPE_PARAM_STRUCT: | |
1397 { | |
1398 int i; | |
1399 for (i = 0; i < NUM_PARAM; i++) | |
1400 if (t->u.param_struct.param[i] != 0) | |
1401 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL); | |
1402 } | |
1403 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO) | |
1404 level = GC_POINTED_TO; | |
1405 else | |
1406 level = GC_USED; | |
1407 t->u.param_struct.stru->gc_used = GC_UNUSED; | |
1408 set_gc_used_type (t->u.param_struct.stru, level, | |
1409 t->u.param_struct.param); | |
1410 break; | 1574 break; |
1411 | 1575 |
1412 default: | 1576 default: |
1413 break; | 1577 break; |
1414 } | 1578 } |
1421 { | 1585 { |
1422 int nbvars = 0; | 1586 int nbvars = 0; |
1423 pair_p p; | 1587 pair_p p; |
1424 for (p = variables; p; p = p->next) | 1588 for (p = variables; p; p = p->next) |
1425 { | 1589 { |
1426 set_gc_used_type (p->type, GC_USED, NULL); | 1590 set_gc_used_type (p->type, GC_USED); |
1427 nbvars++; | 1591 nbvars++; |
1428 }; | 1592 }; |
1429 if (verbosity_level >= 2) | 1593 if (verbosity_level >= 2) |
1430 printf ("%s used %d GTY-ed variables\n", progname, nbvars); | 1594 printf ("%s used %d GTY-ed variables\n", progname, nbvars); |
1431 } | 1595 } |
1441 | 1605 |
1442 static outf_p | 1606 static outf_p |
1443 create_file (const char *name, const char *oname) | 1607 create_file (const char *name, const char *oname) |
1444 { | 1608 { |
1445 static const char *const hdr[] = { | 1609 static const char *const hdr[] = { |
1446 " Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.\n", | 1610 " Copyright (C) 2004-2017 Free Software Foundation, Inc.\n", |
1447 "\n", | 1611 "\n", |
1448 "This file is part of GCC.\n", | 1612 "This file is part of GCC.\n", |
1449 "\n", | 1613 "\n", |
1450 "GCC is free software; you can redistribute it and/or modify it under\n", | 1614 "GCC is free software; you can redistribute it and/or modify it under\n", |
1451 "the terms of the GNU General Public License as published by the Free\n", | 1615 "the terms of the GNU General Public License as published by the Free\n", |
1540 | 1704 |
1541 /* gtype-desc.c is a little special, so we create it here. */ | 1705 /* gtype-desc.c is a little special, so we create it here. */ |
1542 { | 1706 { |
1543 /* The order of files here matters very much. */ | 1707 /* The order of files here matters very much. */ |
1544 static const char *const ifiles[] = { | 1708 static const char *const ifiles[] = { |
1545 "config.h", "system.h", "coretypes.h", "tm.h", | 1709 "config.h", "system.h", "coretypes.h", |
1546 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h", | 1710 "backend.h", "predict.h", "tree.h", |
1547 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h", | 1711 "rtl.h", "gimple.h", "fold-const.h", "insn-codes.h", "splay-tree.h", |
1548 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h", | 1712 "alias.h", "insn-config.h", "flags.h", "expmed.h", "dojump.h", |
1549 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h", | 1713 "explow.h", "calls.h", "cilk.h", "memmodel.h", "emit-rtl.h", "varasm.h", |
1550 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h", | 1714 "stmt.h", "expr.h", "alloc-pool.h", "cselib.h", "insn-addr.h", |
1551 "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h", | 1715 "optabs.h", "libfuncs.h", "debug.h", "internal-fn.h", "gimple-fold.h", |
1552 "target.h", "ipa-prop.h", "lto-streamer.h", "target-globals.h", NULL | 1716 "tree-eh.h", "gimple-iterator.h", "gimple-ssa.h", "tree-cfg.h", |
1717 "tree-vrp.h", "tree-phinodes.h", "ssa-iterators.h", "stringpool.h", | |
1718 "tree-ssanames.h", "tree-ssa-loop.h", "tree-ssa-loop-ivopts.h", | |
1719 "tree-ssa-loop-manip.h", "tree-ssa-loop-niter.h", "tree-into-ssa.h", | |
1720 "tree-dfa.h", "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h", | |
1721 "except.h", "output.h", "cfgloop.h", "target.h", "lto-streamer.h", | |
1722 "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h", | |
1723 "ipa-prop.h", "ipa-fnsummary.h", "dwarf2out.h", "omp-offload.h", NULL | |
1553 }; | 1724 }; |
1554 const char *const *ifp; | 1725 const char *const *ifp; |
1555 outf_p gtype_desc_c; | 1726 outf_p gtype_desc_c; |
1556 | 1727 |
1557 gtype_desc_c = create_file ("GCC", "gtype-desc.c"); | 1728 gtype_desc_c = create_file ("GCC", "gtype-desc.c"); |
1559 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp); | 1730 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp); |
1560 | 1731 |
1561 /* Make sure we handle "cfun" specially. */ | 1732 /* Make sure we handle "cfun" specially. */ |
1562 oprintf (gtype_desc_c, "\n/* See definition in function.h. */\n"); | 1733 oprintf (gtype_desc_c, "\n/* See definition in function.h. */\n"); |
1563 oprintf (gtype_desc_c, "#undef cfun\n"); | 1734 oprintf (gtype_desc_c, "#undef cfun\n"); |
1735 | |
1736 oprintf (gtype_desc_c, | |
1737 "\n" | |
1738 "/* Types with a \"gcc::\" namespace have it stripped\n" | |
1739 " during gengtype parsing. Provide a \"using\" directive\n" | |
1740 " to ensure that the fully-qualified types are found. */\n" | |
1741 "using namespace gcc;\n"); | |
1564 } | 1742 } |
1565 } | 1743 } |
1566 | 1744 |
1567 /* For INPF an input file, return the real basename of INPF, with all | 1745 /* For INPF an input file, return the real basename of INPF, with all |
1568 the directory components skipped. */ | 1746 the directory components skipped. */ |
1569 | 1747 |
1570 static const char * | 1748 static const char * |
1571 get_file_realbasename (const input_file *inpf) | 1749 get_file_realbasename (const input_file *inpf) |
1572 { | 1750 { |
1573 const char *f = get_input_file_name (inpf); | 1751 return lbasename (get_input_file_name (inpf)); |
1574 const char *lastslash = strrchr (f, '/'); | |
1575 | |
1576 return (lastslash != NULL) ? lastslash + 1 : f; | |
1577 } | 1752 } |
1578 | 1753 |
1579 /* For INPF a filename, return the relative path to INPF from | 1754 /* For INPF a filename, return the relative path to INPF from |
1580 $(srcdir) if the latter is a prefix in INPF, NULL otherwise. */ | 1755 $(srcdir) if the latter is a prefix in INPF, NULL otherwise. */ |
1581 | 1756 |
1756 | 1931 |
1757 /* The array of our rules governing file name generation. Rules order | 1932 /* The array of our rules governing file name generation. Rules order |
1758 matters, so change with extreme care! */ | 1933 matters, so change with extreme care! */ |
1759 | 1934 |
1760 struct file_rule_st files_rules[] = { | 1935 struct file_rule_st files_rules[] = { |
1936 /* The general rule assumes that files in subdirectories belong to a | |
1937 particular front-end, and files not in subdirectories are shared. | |
1938 The following rules deal with exceptions - files that are in | |
1939 subdirectories and yet are shared, and files that are top-level, | |
1940 but are not shared. */ | |
1941 | |
1761 /* the c-family/ source directory is special. */ | 1942 /* the c-family/ source directory is special. */ |
1762 { DIR_PREFIX_REGEX "c-family/([[:alnum:]_-]*)\\.c$", | 1943 { DIR_PREFIX_REGEX "c-family/([[:alnum:]_-]*)\\.c$", |
1763 REG_EXTENDED, NULL_REGEX, | 1944 REG_EXTENDED, NULL_REGEX, |
1764 "gt-c-family-$3.h", "c-family/$3.c", NULL_FRULACT}, | 1945 "gt-c-family-$3.h", "c-family/$3.c", NULL_FRULACT}, |
1765 | 1946 |
1766 { DIR_PREFIX_REGEX "c-family/([[:alnum:]_-]*)\\.h$", | 1947 { DIR_PREFIX_REGEX "c-family/([[:alnum:]_-]*)\\.h$", |
1767 REG_EXTENDED, NULL_REGEX, | 1948 REG_EXTENDED, NULL_REGEX, |
1768 "gt-c-family-$3.h", "c-family/$3.h", NULL_FRULACT}, | 1949 "gt-c-family-$3.h", "c-family/$3.h", NULL_FRULACT}, |
1769 | 1950 |
1770 /* Both c-lang.h & c-tree.h gives gt-c-decl.h for c-decl.c ! */ | 1951 /* Both c-lang.h & c-tree.h gives gt-c-c-decl.h for c-decl.c ! */ |
1771 { DIR_PREFIX_REGEX "c-lang\\.h$", | 1952 { DIR_PREFIX_REGEX "c/c-lang\\.h$", |
1772 REG_EXTENDED, NULL_REGEX, "gt-c-decl.h", "c-decl.c", NULL_FRULACT}, | 1953 REG_EXTENDED, NULL_REGEX, "gt-c-c-decl.h", "c/c-decl.c", NULL_FRULACT}, |
1773 | 1954 |
1774 { DIR_PREFIX_REGEX "c-tree\\.h$", | 1955 { DIR_PREFIX_REGEX "c/c-tree\\.h$", |
1775 REG_EXTENDED, NULL_REGEX, "gt-c-decl.h", "c-decl.c", NULL_FRULACT}, | 1956 REG_EXTENDED, NULL_REGEX, "gt-c-c-decl.h", "c/c-decl.c", NULL_FRULACT}, |
1776 | 1957 |
1777 /* cp/cp-tree.h gives gt-cp-tree.h for cp/tree.c ! */ | 1958 /* cp/cp-tree.h gives gt-cp-tree.h for cp/tree.c ! */ |
1778 { DIR_PREFIX_REGEX "cp/cp-tree\\.h$", | 1959 { DIR_PREFIX_REGEX "cp/cp-tree\\.h$", |
1779 REG_EXTENDED, NULL_REGEX, | 1960 REG_EXTENDED, NULL_REGEX, |
1780 "gt-cp-tree.h", "cp/tree.c", NULL_FRULACT }, | 1961 "gt-cp-tree.h", "cp/tree.c", NULL_FRULACT }, |
1787 /* cp/name-lookup.h gives gt-cp-name-lookup.h for cp/name-lookup.c ! */ | 1968 /* cp/name-lookup.h gives gt-cp-name-lookup.h for cp/name-lookup.c ! */ |
1788 { DIR_PREFIX_REGEX "cp/name-lookup\\.h$", | 1969 { DIR_PREFIX_REGEX "cp/name-lookup\\.h$", |
1789 REG_EXTENDED, NULL_REGEX, | 1970 REG_EXTENDED, NULL_REGEX, |
1790 "gt-cp-name-lookup.h", "cp/name-lookup.c", NULL_FRULACT }, | 1971 "gt-cp-name-lookup.h", "cp/name-lookup.c", NULL_FRULACT }, |
1791 | 1972 |
1792 /* objc/objc-act.h fives gt-objc-objc-act.h for objc/objc-act.c ! */ | 1973 /* cp/parser.h gives gt-cp-parser.h for cp/parser.c ! */ |
1974 { DIR_PREFIX_REGEX "cp/parser\\.h$", | |
1975 REG_EXTENDED, NULL_REGEX, | |
1976 "gt-cp-parser.h", "cp/parser.c", NULL_FRULACT }, | |
1977 | |
1978 /* objc/objc-act.h gives gt-objc-objc-act.h for objc/objc-act.c ! */ | |
1793 { DIR_PREFIX_REGEX "objc/objc-act\\.h$", | 1979 { DIR_PREFIX_REGEX "objc/objc-act\\.h$", |
1794 REG_EXTENDED, NULL_REGEX, | 1980 REG_EXTENDED, NULL_REGEX, |
1795 "gt-objc-objc-act.h", "objc/objc-act.c", NULL_FRULACT }, | 1981 "gt-objc-objc-act.h", "objc/objc-act.c", NULL_FRULACT }, |
1796 | 1982 |
1797 /* General cases. For header *.h and source *.c files, we need | 1983 /* objc/objc-map.h gives gt-objc-objc-map.h for objc/objc-map.c ! */ |
1798 * special actions to handle the language. */ | 1984 { DIR_PREFIX_REGEX "objc/objc-map\\.h$", |
1985 REG_EXTENDED, NULL_REGEX, | |
1986 "gt-objc-objc-map.h", "objc/objc-map.c", NULL_FRULACT }, | |
1987 | |
1988 /* General cases. For header *.h and source *.c or *.cc files, we | |
1989 * need special actions to handle the language. */ | |
1799 | 1990 |
1800 /* Source *.c files are using get_file_gtfilename to compute their | 1991 /* Source *.c files are using get_file_gtfilename to compute their |
1801 output_name and get_file_basename to compute their for_name | 1992 output_name and get_file_basename to compute their for_name |
1802 thru the source_dot_c_frul action. */ | 1993 through the source_dot_c_frul action. */ |
1803 { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.c$", | 1994 { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.c$", |
1804 REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.c", source_dot_c_frul}, | 1995 REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.c", source_dot_c_frul}, |
1996 | |
1997 /* Source *.cc files are using get_file_gtfilename to compute their | |
1998 output_name and get_file_basename to compute their for_name | |
1999 through the source_dot_c_frul action. */ | |
2000 { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.cc$", | |
2001 REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.cc", source_dot_c_frul}, | |
2002 | |
1805 /* Common header files get "gtype-desc.c" as their output_name, | 2003 /* Common header files get "gtype-desc.c" as their output_name, |
1806 * while language specific header files are handled specially. So | 2004 * while language specific header files are handled specially. So |
1807 * we need the header_dot_h_frul action. */ | 2005 * we need the header_dot_h_frul action. */ |
1808 { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.h$", | 2006 { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.h$", |
1809 REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.h", header_dot_h_frul}, | 2007 REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.h", header_dot_h_frul}, |
1912 obstack_grow (&str_obstack, filnam + so, eo - so); | 2110 obstack_grow (&str_obstack, filnam + so, eo - so); |
1913 } | 2111 } |
1914 else | 2112 else |
1915 { | 2113 { |
1916 /* This can happen only when files_rules is buggy! */ | 2114 /* This can happen only when files_rules is buggy! */ |
1917 gcc_unreachable(); | 2115 gcc_unreachable (); |
1918 } | 2116 } |
1919 /* Always skip the character after the dollar. */ | 2117 /* Always skip the character after the dollar. */ |
1920 pt++; | 2118 pt++; |
1921 } | 2119 } |
1922 else | 2120 else |
1923 obstack_1grow (&str_obstack, c); | 2121 obstack_1grow (&str_obstack, c); |
1924 } | 2122 } |
1925 obstack_1grow (&str_obstack, '\0'); | 2123 obstack_1grow (&str_obstack, '\0'); |
1926 rawstr = XOBFINISH (&str_obstack, char *); | 2124 rawstr = XOBFINISH (&str_obstack, char *); |
1927 str = xstrdup (rawstr); | 2125 str = xstrdup (rawstr); |
1928 obstack_free (&str_obstack, rawstr); | 2126 obstack_free (&str_obstack, NULL); |
1929 DBGPRINTF ("matched replacement %s", str); | 2127 DBGPRINTF ("matched replacement %s", str); |
1930 rawstr = NULL; | 2128 rawstr = NULL; |
1931 return str; | 2129 return str; |
1932 } | 2130 } |
1933 | 2131 |
1934 | 2132 |
1935 /* An output file, suitable for definitions, that can see declarations | 2133 /* An output file, suitable for definitions, that can see declarations |
1936 made in INPF and is linked into every language that uses INPF. | 2134 made in INPF and is linked into every language that uses INPF. |
1937 Since the the result is cached inside INPF, that argument cannot be | 2135 Since the result is cached inside INPF, that argument cannot be |
1938 declared constant, but is "almost" constant. */ | 2136 declared constant, but is "almost" constant. */ |
1939 | 2137 |
1940 outf_p | 2138 outf_p |
1941 get_output_file_with_visibility (input_file *inpf) | 2139 get_output_file_with_visibility (input_file *inpf) |
1942 { | 2140 { |
1973 inpfname = get_input_file_name (inpf); | 2171 inpfname = get_input_file_name (inpf); |
1974 | 2172 |
1975 /* Try each rule in sequence in files_rules until one is triggered. */ | 2173 /* Try each rule in sequence in files_rules until one is triggered. */ |
1976 { | 2174 { |
1977 int rulix = 0; | 2175 int rulix = 0; |
1978 DBGPRINTF ("passing input file @ %p named %s thru the files_rules", | 2176 DBGPRINTF ("passing input file @ %p named %s through the files_rules", |
1979 (void*) inpf, inpfname); | 2177 (void*) inpf, inpfname); |
1980 | 2178 |
1981 for (; files_rules[rulix].frul_srcexpr != NULL; rulix++) | 2179 for (; files_rules[rulix].frul_srcexpr != NULL; rulix++) |
1982 { | 2180 { |
1983 DBGPRINTF ("rulix#%d srcexpr %s", | 2181 DBGPRINTF ("rulix#%d srcexpr %s", |
2057 } | 2255 } |
2058 } | 2256 } |
2059 } | 2257 } |
2060 if (!output_name || !for_name) | 2258 if (!output_name || !for_name) |
2061 { | 2259 { |
2062 /* This is impossible, and could only happen if the files_rules is | 2260 /* This should not be possible, and could only happen if the |
2063 incomplete or buggy. */ | 2261 files_rules is incomplete or buggy. */ |
2064 gcc_unreachable (); | 2262 fatal ("failed to compute output name for %s", inpfname); |
2065 } | 2263 } |
2066 | 2264 |
2067 /* Look through to see if we've ever seen this output filename | 2265 /* Look through to see if we've ever seen this output filename |
2068 before. If found, cache the result in inpf. */ | 2266 before. If found, cache the result in inpf. */ |
2069 for (r = output_files; r; r = r->next) | 2267 for (r = output_files; r; r = r->next) |
2070 if (strcmp (r->name, output_name) == 0) | 2268 if (filename_cmp (r->name, output_name) == 0) |
2071 { | 2269 { |
2072 inpf->inpoutf = r; | 2270 inpf->inpoutf = r; |
2073 DBGPRINTF ("found r @ %p for output_name %s for_name %s", (void*)r, | 2271 DBGPRINTF ("found r @ %p for output_name %s for_name %s", (void*)r, |
2074 output_name, for_name); | 2272 output_name, for_name); |
2075 return r; | 2273 return r; |
2120 { | 2318 { |
2121 equal = false; | 2319 equal = false; |
2122 break; | 2320 break; |
2123 } | 2321 } |
2124 } | 2322 } |
2323 if (equal && EOF != fgetc (newfile)) | |
2324 equal = false; | |
2125 fclose (newfile); | 2325 fclose (newfile); |
2126 return equal; | 2326 return equal; |
2127 } | 2327 } |
2128 | 2328 |
2129 /* Copy the output to its final destination, | 2329 /* Copy the output to its final destination, |
2135 int nbwrittenfiles = 0; | 2335 int nbwrittenfiles = 0; |
2136 outf_p of; | 2336 outf_p of; |
2137 | 2337 |
2138 for (of = output_files; of; of = of->next) | 2338 for (of = output_files; of; of = of->next) |
2139 { | 2339 { |
2140 | |
2141 if (!is_file_equal (of)) | 2340 if (!is_file_equal (of)) |
2142 { | 2341 { |
2143 FILE *newfile = NULL; | 2342 FILE *newfile = NULL; |
2144 char *backupname = NULL; | 2343 char *backupname = NULL; |
2145 /* Back up the old version of the output file gt-FOO.c as | 2344 /* Back up the old version of the output file gt-FOO.c as |
2207 const char *param_prefix; | 2406 const char *param_prefix; |
2208 const char *subfield_marker_routine; | 2407 const char *subfield_marker_routine; |
2209 const char *marker_routine; | 2408 const char *marker_routine; |
2210 const char *reorder_note_routine; | 2409 const char *reorder_note_routine; |
2211 const char *comment; | 2410 const char *comment; |
2212 int skip_hooks; /* skip hook generation if non zero */ | 2411 enum write_types_kinds kind; |
2213 }; | 2412 }; |
2214 | 2413 |
2215 static void output_escaped_param (struct walk_type_data *d, | 2414 static void output_escaped_param (struct walk_type_data *d, |
2216 const char *, const char *); | 2415 const char *, const char *); |
2217 static void output_mangled_typename (outf_p, const_type_p); | 2416 static void output_mangled_typename (outf_p, const_type_p); |
2218 static void walk_type (type_p t, struct walk_type_data *d); | 2417 static void walk_type (type_p t, struct walk_type_data *d); |
2219 static void write_func_for_structure (type_p orig_s, type_p s, type_p *param, | 2418 static void write_func_for_structure (type_p orig_s, type_p s, |
2220 const struct write_types_data *wtd); | 2419 const struct write_types_data *wtd); |
2221 static void write_types_process_field | 2420 static void write_types_process_field |
2222 (type_p f, const struct walk_type_data *d); | 2421 (type_p f, const struct walk_type_data *d); |
2223 static void write_types (outf_p output_header, | 2422 static void write_types (outf_p output_header, |
2224 type_p structures, | 2423 type_p structures, |
2225 type_p param_structs, | |
2226 const struct write_types_data *wtd); | 2424 const struct write_types_data *wtd); |
2227 static void write_types_local_process_field | 2425 static void write_types_local_process_field |
2228 (type_p f, const struct walk_type_data *d); | 2426 (type_p f, const struct walk_type_data *d); |
2229 static void write_local_func_for_structure | 2427 static void write_local_func_for_structure (const_type_p orig_s, type_p s); |
2230 (const_type_p orig_s, type_p s, type_p *param); | |
2231 static void write_local (outf_p output_header, | 2428 static void write_local (outf_p output_header, |
2232 type_p structures, type_p param_structs); | 2429 type_p structures); |
2233 static void write_enum_defn (type_p structures, type_p param_structs); | |
2234 static int contains_scalar_p (type_p t); | 2430 static int contains_scalar_p (type_p t); |
2235 static void put_mangled_filename (outf_p, const input_file *); | 2431 static void put_mangled_filename (outf_p, const input_file *); |
2236 static void finish_root_table (struct flist *flp, const char *pfx, | 2432 static void finish_root_table (struct flist *flp, const char *pfx, |
2237 const char *tname, const char *lastname, | 2433 const char *tname, const char *lastname, |
2238 const char *name); | 2434 const char *name); |
2239 static void write_root (outf_p, pair_p, type_p, const char *, int, | 2435 static void write_root (outf_p, pair_p, type_p, const char *, int, |
2240 struct fileloc *, const char *, bool); | 2436 struct fileloc *, bool); |
2241 static void write_array (outf_p f, pair_p v, | 2437 static void write_array (outf_p f, pair_p v, |
2242 const struct write_types_data *wtd); | 2438 const struct write_types_data *wtd); |
2243 static void write_roots (pair_p, bool); | 2439 static void write_roots (pair_p, bool); |
2244 | 2440 |
2245 /* Parameters for walk_type. */ | 2441 /* Parameters for walk_type. */ |
2254 const char *prev_val[4]; | 2450 const char *prev_val[4]; |
2255 int indent; | 2451 int indent; |
2256 int counter; | 2452 int counter; |
2257 const struct fileloc *line; | 2453 const struct fileloc *line; |
2258 lang_bitmap bitmap; | 2454 lang_bitmap bitmap; |
2259 type_p *param; | |
2260 int used_length; | 2455 int used_length; |
2261 type_p orig_s; | 2456 type_p orig_s; |
2262 const char *reorder_fn; | 2457 const char *reorder_fn; |
2263 bool needs_cast_p; | 2458 bool needs_cast_p; |
2264 bool fn_wants_lvalue; | 2459 bool fn_wants_lvalue; |
2460 bool in_record_p; | |
2461 int loopcounter; | |
2462 bool in_ptr_field; | |
2463 bool have_this_obj; | |
2265 }; | 2464 }; |
2465 | |
2466 | |
2467 /* Given a string TYPE_NAME, representing a C++ typename, return a valid | |
2468 pre-processor identifier to use in a #define directive. This replaces | |
2469 special characters used in C++ identifiers like '>', '<' and ':' with | |
2470 '_'. | |
2471 | |
2472 If no C++ special characters are found in TYPE_NAME, return | |
2473 TYPE_NAME. Otherwise, return a copy of TYPE_NAME with the special | |
2474 characters replaced with '_'. In this case, the caller is | |
2475 responsible for freeing the allocated string. */ | |
2476 | |
2477 static const char * | |
2478 filter_type_name (const char *type_name) | |
2479 { | |
2480 if (strchr (type_name, '<') || strchr (type_name, ':')) | |
2481 { | |
2482 size_t i; | |
2483 char *s = xstrdup (type_name); | |
2484 for (i = 0; i < strlen (s); i++) | |
2485 if (s[i] == '<' || s[i] == '>' || s[i] == ':' || s[i] == ',' | |
2486 || s[i] == '*') | |
2487 s[i] = '_'; | |
2488 return s; | |
2489 } | |
2490 else | |
2491 return type_name; | |
2492 } | |
2493 | |
2266 | 2494 |
2267 /* Print a mangled name representing T to OF. */ | 2495 /* Print a mangled name representing T to OF. */ |
2268 | 2496 |
2269 static void | 2497 static void |
2270 output_mangled_typename (outf_p of, const_type_p t) | 2498 output_mangled_typename (outf_p of, const_type_p t) |
2273 oprintf (of, "Z"); | 2501 oprintf (of, "Z"); |
2274 else | 2502 else |
2275 switch (t->kind) | 2503 switch (t->kind) |
2276 { | 2504 { |
2277 case TYPE_NONE: | 2505 case TYPE_NONE: |
2506 case TYPE_UNDEFINED: | |
2278 gcc_unreachable (); | 2507 gcc_unreachable (); |
2279 break; | 2508 break; |
2280 case TYPE_POINTER: | 2509 case TYPE_POINTER: |
2281 oprintf (of, "P"); | 2510 oprintf (of, "P"); |
2282 output_mangled_typename (of, t->u.p); | 2511 output_mangled_typename (of, t->u.p); |
2288 oprintf (of, "S"); | 2517 oprintf (of, "S"); |
2289 break; | 2518 break; |
2290 case TYPE_STRUCT: | 2519 case TYPE_STRUCT: |
2291 case TYPE_UNION: | 2520 case TYPE_UNION: |
2292 case TYPE_LANG_STRUCT: | 2521 case TYPE_LANG_STRUCT: |
2293 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), | 2522 case TYPE_USER_STRUCT: |
2294 t->u.s.tag); | |
2295 break; | |
2296 case TYPE_PARAM_STRUCT: | |
2297 { | 2523 { |
2298 int i; | 2524 /* For references to classes within an inheritance hierarchy, |
2299 for (i = 0; i < NUM_PARAM; i++) | 2525 only ever reference the ultimate base class, since only |
2300 if (t->u.param_struct.param[i] != NULL) | 2526 it will have gt_ functions. */ |
2301 output_mangled_typename (of, t->u.param_struct.param[i]); | 2527 t = get_ultimate_base_class (t); |
2302 output_mangled_typename (of, t->u.param_struct.stru); | 2528 const char *id_for_tag = filter_type_name (t->u.s.tag); |
2529 oprintf (of, "%lu%s", (unsigned long) strlen (id_for_tag), | |
2530 id_for_tag); | |
2531 if (id_for_tag != t->u.s.tag) | |
2532 free (CONST_CAST (char *, id_for_tag)); | |
2303 } | 2533 } |
2304 break; | 2534 break; |
2305 case TYPE_ARRAY: | 2535 case TYPE_ARRAY: |
2306 gcc_unreachable (); | 2536 gcc_unreachable (); |
2307 } | 2537 } |
2346 error_at_line (d->line, "`%s' option contains bad escape %c%c", | 2576 error_at_line (d->line, "`%s' option contains bad escape %c%c", |
2347 oname, '%', *p); | 2577 oname, '%', *p); |
2348 } | 2578 } |
2349 } | 2579 } |
2350 | 2580 |
2581 const char * | |
2582 get_string_option (options_p opt, const char *key) | |
2583 { | |
2584 for (; opt; opt = opt->next) | |
2585 if (strcmp (opt->name, key) == 0) | |
2586 return opt->info.string; | |
2587 return NULL; | |
2588 } | |
2589 | |
2590 /* Machinery for avoiding duplicate tags within switch statements. */ | |
2591 struct seen_tag | |
2592 { | |
2593 const char *tag; | |
2594 struct seen_tag *next; | |
2595 }; | |
2596 | |
2597 int | |
2598 already_seen_tag (struct seen_tag *seen_tags, const char *tag) | |
2599 { | |
2600 /* Linear search, so O(n^2), but n is currently small. */ | |
2601 while (seen_tags) | |
2602 { | |
2603 if (!strcmp (seen_tags->tag, tag)) | |
2604 return 1; | |
2605 seen_tags = seen_tags->next; | |
2606 } | |
2607 /* Not yet seen this tag. */ | |
2608 return 0; | |
2609 } | |
2610 | |
2611 void | |
2612 mark_tag_as_seen (struct seen_tag **seen_tags, const char *tag) | |
2613 { | |
2614 /* Add to front of linked list. */ | |
2615 struct seen_tag *new_node = XCNEW (struct seen_tag); | |
2616 new_node->tag = tag; | |
2617 new_node->next = *seen_tags; | |
2618 *seen_tags = new_node; | |
2619 } | |
2620 | |
2621 static void | |
2622 walk_subclasses (type_p base, struct walk_type_data *d, | |
2623 struct seen_tag **seen_tags) | |
2624 { | |
2625 for (type_p sub = base->u.s.first_subclass; sub != NULL; | |
2626 sub = sub->u.s.next_sibling_class) | |
2627 { | |
2628 const char *type_tag = get_string_option (sub->u.s.opt, "tag"); | |
2629 if (type_tag && !already_seen_tag (*seen_tags, type_tag)) | |
2630 { | |
2631 mark_tag_as_seen (seen_tags, type_tag); | |
2632 oprintf (d->of, "%*scase %s:\n", d->indent, "", type_tag); | |
2633 d->indent += 2; | |
2634 oprintf (d->of, "%*s{\n", d->indent, ""); | |
2635 d->indent += 2; | |
2636 oprintf (d->of, "%*s%s *sub = static_cast <%s *> (x);\n", | |
2637 d->indent, "", sub->u.s.tag, sub->u.s.tag); | |
2638 const char *old_val = d->val; | |
2639 d->val = "(*sub)"; | |
2640 walk_type (sub, d); | |
2641 d->val = old_val; | |
2642 d->indent -= 2; | |
2643 oprintf (d->of, "%*s}\n", d->indent, ""); | |
2644 oprintf (d->of, "%*sbreak;\n", d->indent, ""); | |
2645 d->indent -= 2; | |
2646 } | |
2647 walk_subclasses (sub, d, seen_tags); | |
2648 } | |
2649 } | |
2650 | |
2351 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL, | 2651 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL, |
2352 which is of type T. Write code to D->OF to constrain execution (at | 2652 which is of type T. Write code to D->OF to constrain execution (at |
2353 the point that D->PROCESS_FIELD is called) to the appropriate | 2653 the point that D->PROCESS_FIELD is called) to the appropriate |
2354 cases. Call D->PROCESS_FIELD on subobjects before calling it on | 2654 cases. Call D->PROCESS_FIELD on subobjects before calling it on |
2355 pointers to those objects. D->PREV_VAL lists the objects | 2655 pointers to those objects. D->PREV_VAL lists the objects |
2356 containing the current object, D->OPT is a list of options to | 2656 containing the current object, D->OPT is a list of options to |
2357 apply, D->INDENT is the current indentation level, D->LINE is used | 2657 apply, D->INDENT is the current indentation level, D->LINE is used |
2358 to print error messages, D->BITMAP indicates which languages to | 2658 to print error messages, D->BITMAP indicates which languages to |
2359 print the structure for, and D->PARAM is the current parameter | 2659 print the structure for. */ |
2360 (from an enclosing param_is option). */ | |
2361 | 2660 |
2362 static void | 2661 static void |
2363 walk_type (type_p t, struct walk_type_data *d) | 2662 walk_type (type_p t, struct walk_type_data *d) |
2364 { | 2663 { |
2365 const char *length = NULL; | 2664 const char *length = NULL; |
2366 const char *desc = NULL; | 2665 const char *desc = NULL; |
2666 const char *type_tag = NULL; | |
2367 int maybe_undef_p = 0; | 2667 int maybe_undef_p = 0; |
2368 int use_param_num = -1; | 2668 int atomic_p = 0; |
2369 int use_params_p = 0; | |
2370 options_p oo; | 2669 options_p oo; |
2371 const struct nested_ptr_data *nested_ptr_d = NULL; | 2670 const struct nested_ptr_data *nested_ptr_d = NULL; |
2372 | 2671 |
2373 d->needs_cast_p = false; | 2672 d->needs_cast_p = false; |
2374 for (oo = d->opt; oo; oo = oo->next) | 2673 for (oo = d->opt; oo; oo = oo->next) |
2375 if (strcmp (oo->name, "length") == 0 && oo->kind == OPTION_STRING) | 2674 if (strcmp (oo->name, "length") == 0 && oo->kind == OPTION_STRING) |
2376 length = oo->info.string; | 2675 length = oo->info.string; |
2377 else if (strcmp (oo->name, "maybe_undef") == 0) | 2676 else if (strcmp (oo->name, "maybe_undef") == 0) |
2378 maybe_undef_p = 1; | 2677 maybe_undef_p = 1; |
2379 else if (strncmp (oo->name, "use_param", 9) == 0 | |
2380 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9]))) | |
2381 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0'; | |
2382 else if (strcmp (oo->name, "use_params") == 0) | |
2383 use_params_p = 1; | |
2384 else if (strcmp (oo->name, "desc") == 0 && oo->kind == OPTION_STRING) | 2678 else if (strcmp (oo->name, "desc") == 0 && oo->kind == OPTION_STRING) |
2385 desc = oo->info.string; | 2679 desc = oo->info.string; |
2386 else if (strcmp (oo->name, "mark_hook") == 0) | |
2387 ; | |
2388 else if (strcmp (oo->name, "nested_ptr") == 0 | 2680 else if (strcmp (oo->name, "nested_ptr") == 0 |
2389 && oo->kind == OPTION_NESTED) | 2681 && oo->kind == OPTION_NESTED) |
2390 nested_ptr_d = (const struct nested_ptr_data *) oo->info.nested; | 2682 nested_ptr_d = (const struct nested_ptr_data *) oo->info.nested; |
2391 else if (strcmp (oo->name, "dot") == 0) | 2683 else if (strcmp (oo->name, "dot") == 0) |
2392 ; | 2684 ; |
2393 else if (strcmp (oo->name, "tag") == 0) | 2685 else if (strcmp (oo->name, "tag") == 0) |
2394 ; | 2686 type_tag = oo->info.string; |
2395 else if (strcmp (oo->name, "special") == 0) | 2687 else if (strcmp (oo->name, "special") == 0) |
2396 ; | 2688 ; |
2397 else if (strcmp (oo->name, "skip") == 0) | 2689 else if (strcmp (oo->name, "skip") == 0) |
2398 ; | 2690 ; |
2691 else if (strcmp (oo->name, "atomic") == 0) | |
2692 atomic_p = 1; | |
2399 else if (strcmp (oo->name, "default") == 0) | 2693 else if (strcmp (oo->name, "default") == 0) |
2400 ; | |
2401 else if (strcmp (oo->name, "param_is") == 0) | |
2402 ; | |
2403 else if (strncmp (oo->name, "param", 5) == 0 | |
2404 && ISDIGIT (oo->name[5]) && strcmp (oo->name + 6, "_is") == 0) | |
2405 ; | 2694 ; |
2406 else if (strcmp (oo->name, "chain_next") == 0) | 2695 else if (strcmp (oo->name, "chain_next") == 0) |
2407 ; | 2696 ; |
2408 else if (strcmp (oo->name, "chain_prev") == 0) | 2697 else if (strcmp (oo->name, "chain_prev") == 0) |
2409 ; | 2698 ; |
2411 ; | 2700 ; |
2412 else if (strcmp (oo->name, "reorder") == 0) | 2701 else if (strcmp (oo->name, "reorder") == 0) |
2413 ; | 2702 ; |
2414 else if (strcmp (oo->name, "variable_size") == 0) | 2703 else if (strcmp (oo->name, "variable_size") == 0) |
2415 ; | 2704 ; |
2705 else if (strcmp (oo->name, "for_user") == 0) | |
2706 ; | |
2416 else | 2707 else |
2417 error_at_line (d->line, "unknown option `%s'\n", oo->name); | 2708 error_at_line (d->line, "unknown option `%s'\n", oo->name); |
2418 | 2709 |
2419 if (d->used_length) | 2710 if (d->used_length) |
2420 length = NULL; | 2711 length = NULL; |
2421 | 2712 |
2422 if (use_params_p) | |
2423 { | |
2424 int pointer_p = t->kind == TYPE_POINTER; | |
2425 | |
2426 if (pointer_p) | |
2427 t = t->u.p; | |
2428 if (!UNION_OR_STRUCT_P (t)) | |
2429 error_at_line (d->line, "`use_params' option on unimplemented type"); | |
2430 else | |
2431 t = find_param_structure (t, d->param); | |
2432 if (pointer_p) | |
2433 t = create_pointer (t); | |
2434 } | |
2435 | |
2436 if (use_param_num != -1) | |
2437 { | |
2438 if (d->param != NULL && d->param[use_param_num] != NULL) | |
2439 { | |
2440 type_p nt = d->param[use_param_num]; | |
2441 | |
2442 if (t->kind == TYPE_ARRAY) | |
2443 nt = create_array (nt, t->u.a.len); | |
2444 else if (length != NULL && t->kind == TYPE_POINTER) | |
2445 nt = create_pointer (nt); | |
2446 d->needs_cast_p = (t->kind != TYPE_POINTER | |
2447 && (nt->kind == TYPE_POINTER | |
2448 || nt->kind == TYPE_STRING)); | |
2449 t = nt; | |
2450 } | |
2451 else | |
2452 error_at_line (d->line, "no parameter defined for `%s'", d->val); | |
2453 } | |
2454 | |
2455 if (maybe_undef_p | 2713 if (maybe_undef_p |
2456 && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p))) | 2714 && (t->kind != TYPE_POINTER || !union_or_struct_p (t->u.p))) |
2457 { | 2715 { |
2458 error_at_line (d->line, | 2716 error_at_line (d->line, |
2459 "field `%s' has invalid option `maybe_undef_p'\n", | 2717 "field `%s' has invalid option `maybe_undef_p'\n", |
2460 d->val); | 2718 d->val); |
2461 return; | 2719 return; |
2462 } | 2720 } |
2463 | 2721 |
2722 if (atomic_p && (t->kind != TYPE_POINTER) && (t->kind != TYPE_STRING)) | |
2723 { | |
2724 error_at_line (d->line, "field `%s' has invalid option `atomic'\n", d->val); | |
2725 return; | |
2726 } | |
2727 | |
2464 switch (t->kind) | 2728 switch (t->kind) |
2465 { | 2729 { |
2466 case TYPE_SCALAR: | 2730 case TYPE_SCALAR: |
2467 case TYPE_STRING: | 2731 case TYPE_STRING: |
2468 d->process_field (t, d); | 2732 d->process_field (t, d); |
2469 break; | 2733 break; |
2470 | 2734 |
2471 case TYPE_POINTER: | 2735 case TYPE_POINTER: |
2472 { | 2736 { |
2737 d->in_ptr_field = true; | |
2473 if (maybe_undef_p && t->u.p->u.s.line.file == NULL) | 2738 if (maybe_undef_p && t->u.p->u.s.line.file == NULL) |
2474 { | 2739 { |
2475 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val); | 2740 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val); |
2476 break; | 2741 break; |
2477 } | 2742 } |
2478 | 2743 |
2744 /* If a pointer type is marked as "atomic", we process the | |
2745 field itself, but we don't walk the data that they point to. | |
2746 | |
2747 There are two main cases where we walk types: to mark | |
2748 pointers that are reachable, and to relocate pointers when | |
2749 writing a PCH file. In both cases, an atomic pointer is | |
2750 itself marked or relocated, but the memory that it points | |
2751 to is left untouched. In the case of PCH, that memory will | |
2752 be read/written unchanged to the PCH file. */ | |
2753 if (atomic_p) | |
2754 { | |
2755 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val); | |
2756 d->indent += 2; | |
2757 d->process_field (t, d); | |
2758 d->indent -= 2; | |
2759 oprintf (d->of, "%*s}\n", d->indent, ""); | |
2760 break; | |
2761 } | |
2762 | |
2479 if (!length) | 2763 if (!length) |
2480 { | 2764 { |
2481 if (!UNION_OR_STRUCT_P (t->u.p) | 2765 if (!union_or_struct_p (t->u.p)) |
2482 && t->u.p->kind != TYPE_PARAM_STRUCT) | |
2483 { | 2766 { |
2484 error_at_line (d->line, | 2767 error_at_line (d->line, |
2485 "field `%s' is pointer to unimplemented type", | 2768 "field `%s' is pointer to unimplemented type", |
2486 d->val); | 2769 d->val); |
2487 break; | 2770 break; |
2489 | 2772 |
2490 if (nested_ptr_d) | 2773 if (nested_ptr_d) |
2491 { | 2774 { |
2492 const char *oldprevval2 = d->prev_val[2]; | 2775 const char *oldprevval2 = d->prev_val[2]; |
2493 | 2776 |
2494 if (!UNION_OR_STRUCT_P (nested_ptr_d->type)) | 2777 if (!union_or_struct_p (nested_ptr_d->type)) |
2495 { | 2778 { |
2496 error_at_line (d->line, | 2779 error_at_line (d->line, |
2497 "field `%s' has invalid " | 2780 "field `%s' has invalid " |
2498 "option `nested_ptr'\n", d->val); | 2781 "option `nested_ptr'\n", d->val); |
2499 return; | 2782 return; |
2533 else | 2816 else |
2534 d->process_field (t->u.p, d); | 2817 d->process_field (t->u.p, d); |
2535 } | 2818 } |
2536 else | 2819 else |
2537 { | 2820 { |
2538 int loopcounter = d->counter++; | 2821 int loopcounter = d->loopcounter; |
2539 const char *oldval = d->val; | 2822 const char *oldval = d->val; |
2540 const char *oldprevval3 = d->prev_val[3]; | 2823 const char *oldprevval3 = d->prev_val[3]; |
2541 char *newval; | 2824 char *newval; |
2542 | 2825 |
2543 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val); | 2826 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val); |
2544 d->indent += 2; | 2827 d->indent += 2; |
2545 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter); | 2828 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter); |
2546 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, | 2829 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, |
2547 "", loopcounter, loopcounter); | 2830 "", loopcounter, loopcounter); |
2548 output_escaped_param (d, length, "length"); | 2831 if (!d->in_record_p) |
2832 output_escaped_param (d, length, "length"); | |
2833 else | |
2834 oprintf (d->of, "l%d", loopcounter); | |
2835 if (d->have_this_obj) | |
2836 /* Try to unswitch loops (see PR53880). */ | |
2837 oprintf (d->of, ") && ((void *)%s == this_obj", oldval); | |
2549 oprintf (d->of, "); i%d++) {\n", loopcounter); | 2838 oprintf (d->of, "); i%d++) {\n", loopcounter); |
2550 d->indent += 2; | 2839 d->indent += 2; |
2551 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter); | 2840 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter); |
2552 d->used_length = 1; | 2841 d->used_length = 1; |
2553 d->prev_val[3] = oldval; | 2842 d->prev_val[3] = oldval; |
2560 oprintf (d->of, "%*s}\n", d->indent, ""); | 2849 oprintf (d->of, "%*s}\n", d->indent, ""); |
2561 d->process_field (t, d); | 2850 d->process_field (t, d); |
2562 d->indent -= 2; | 2851 d->indent -= 2; |
2563 oprintf (d->of, "%*s}\n", d->indent, ""); | 2852 oprintf (d->of, "%*s}\n", d->indent, ""); |
2564 } | 2853 } |
2854 d->in_ptr_field = false; | |
2565 } | 2855 } |
2566 break; | 2856 break; |
2567 | 2857 |
2568 case TYPE_ARRAY: | 2858 case TYPE_ARRAY: |
2569 { | 2859 { |
2570 int loopcounter = d->counter++; | 2860 int loopcounter; |
2571 const char *oldval = d->val; | 2861 const char *oldval = d->val; |
2572 char *newval; | 2862 char *newval; |
2573 | 2863 |
2574 /* If it's an array of scalars, we optimize by not generating | 2864 /* If it's an array of scalars, we optimize by not generating |
2575 any code. */ | 2865 any code. */ |
2576 if (t->u.a.p->kind == TYPE_SCALAR) | 2866 if (t->u.a.p->kind == TYPE_SCALAR) |
2577 break; | 2867 break; |
2868 | |
2869 if (length) | |
2870 loopcounter = d->loopcounter; | |
2871 else | |
2872 loopcounter = d->counter++; | |
2578 | 2873 |
2579 /* When walking an array, compute the length and store it in a | 2874 /* When walking an array, compute the length and store it in a |
2580 local variable before walking the array elements, instead of | 2875 local variable before walking the array elements, instead of |
2581 recomputing the length expression each time through the loop. | 2876 recomputing the length expression each time through the loop. |
2582 This is necessary to handle tcc_vl_exp objects like CALL_EXPR, | 2877 This is necessary to handle tcc_vl_exp objects like CALL_EXPR, |
2584 because otherwise that operand can get overwritten on the | 2879 because otherwise that operand can get overwritten on the |
2585 first iteration. */ | 2880 first iteration. */ |
2586 oprintf (d->of, "%*s{\n", d->indent, ""); | 2881 oprintf (d->of, "%*s{\n", d->indent, ""); |
2587 d->indent += 2; | 2882 d->indent += 2; |
2588 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter); | 2883 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter); |
2589 oprintf (d->of, "%*ssize_t l%d = (size_t)(", | 2884 if (!d->in_record_p || !length) |
2590 d->indent, "", loopcounter); | 2885 { |
2591 if (length) | 2886 oprintf (d->of, "%*ssize_t l%d = (size_t)(", |
2592 output_escaped_param (d, length, "length"); | 2887 d->indent, "", loopcounter); |
2593 else | 2888 if (length) |
2594 oprintf (d->of, "%s", t->u.a.len); | 2889 output_escaped_param (d, length, "length"); |
2595 oprintf (d->of, ");\n"); | 2890 else |
2891 oprintf (d->of, "%s", t->u.a.len); | |
2892 oprintf (d->of, ");\n"); | |
2893 } | |
2596 | 2894 |
2597 oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n", | 2895 oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n", |
2598 d->indent, "", | 2896 d->indent, "", |
2599 loopcounter, loopcounter, loopcounter, loopcounter); | 2897 loopcounter, loopcounter, loopcounter, loopcounter); |
2600 d->indent += 2; | 2898 d->indent += 2; |
2619 const char *oldprevval1 = d->prev_val[1]; | 2917 const char *oldprevval1 = d->prev_val[1]; |
2620 const char *oldprevval2 = d->prev_val[2]; | 2918 const char *oldprevval2 = d->prev_val[2]; |
2621 const int union_p = t->kind == TYPE_UNION; | 2919 const int union_p = t->kind == TYPE_UNION; |
2622 int seen_default_p = 0; | 2920 int seen_default_p = 0; |
2623 options_p o; | 2921 options_p o; |
2922 int lengths_seen = 0; | |
2923 int endcounter; | |
2924 bool any_length_seen = false; | |
2624 | 2925 |
2625 if (!t->u.s.line.file) | 2926 if (!t->u.s.line.file) |
2626 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag); | 2927 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag); |
2627 | 2928 |
2628 if ((d->bitmap & t->u.s.bitmap) != d->bitmap) | 2929 if ((d->bitmap & t->u.s.bitmap) != d->bitmap) |
2648 error_at_line (d->line, | 2949 error_at_line (d->line, |
2649 "missing `desc' option for union `%s'", | 2950 "missing `desc' option for union `%s'", |
2650 t->u.s.tag); | 2951 t->u.s.tag); |
2651 desc = "1"; | 2952 desc = "1"; |
2652 } | 2953 } |
2653 oprintf (d->of, "%*sswitch (", d->indent, ""); | 2954 oprintf (d->of, "%*sswitch ((int) (", d->indent, ""); |
2654 output_escaped_param (d, desc, "desc"); | 2955 output_escaped_param (d, desc, "desc"); |
2655 oprintf (d->of, ")\n"); | 2956 oprintf (d->of, "))\n"); |
2656 d->indent += 2; | 2957 d->indent += 2; |
2657 oprintf (d->of, "%*s{\n", d->indent, ""); | 2958 oprintf (d->of, "%*s{\n", d->indent, ""); |
2658 } | 2959 } |
2659 for (f = t->u.s.fields; f; f = f->next) | 2960 else if (desc) |
2961 { | |
2962 /* We have a "desc" option on a struct, signifying the | |
2963 base class within a GC-managed inheritance hierarchy. | |
2964 The current code specialcases the base class, then walks | |
2965 into subclasses, recursing into this routine to handle them. | |
2966 This organization requires the base class to have a case in | |
2967 the switch statement, and hence a tag value is mandatory | |
2968 for the base class. This restriction could be removed, but | |
2969 it would require some restructing of this code. */ | |
2970 if (!type_tag) | |
2971 { | |
2972 error_at_line (d->line, | |
2973 "missing `tag' option for type `%s'", | |
2974 t->u.s.tag); | |
2975 } | |
2976 oprintf (d->of, "%*sswitch ((int) (", d->indent, ""); | |
2977 output_escaped_param (d, desc, "desc"); | |
2978 oprintf (d->of, "))\n"); | |
2979 d->indent += 2; | |
2980 oprintf (d->of, "%*s{\n", d->indent, ""); | |
2981 oprintf (d->of, "%*scase %s:\n", d->indent, "", type_tag); | |
2982 d->indent += 2; | |
2983 } | |
2984 | |
2985 FOR_ALL_INHERITED_FIELDS (t, f) | |
2986 { | |
2987 options_p oo; | |
2988 int skip_p = 0; | |
2989 const char *fieldlength = NULL; | |
2990 | |
2991 d->reorder_fn = NULL; | |
2992 for (oo = f->opt; oo; oo = oo->next) | |
2993 if (strcmp (oo->name, "skip") == 0) | |
2994 skip_p = 1; | |
2995 else if (strcmp (oo->name, "length") == 0 | |
2996 && oo->kind == OPTION_STRING) | |
2997 fieldlength = oo->info.string; | |
2998 | |
2999 if (skip_p) | |
3000 continue; | |
3001 if (fieldlength) | |
3002 { | |
3003 lengths_seen++; | |
3004 d->counter++; | |
3005 if (!union_p) | |
3006 { | |
3007 if (!any_length_seen) | |
3008 { | |
3009 oprintf (d->of, "%*s{\n", d->indent, ""); | |
3010 d->indent += 2; | |
3011 } | |
3012 any_length_seen = true; | |
3013 | |
3014 oprintf (d->of, "%*ssize_t l%d = (size_t)(", | |
3015 d->indent, "", d->counter - 1); | |
3016 output_escaped_param (d, fieldlength, "length"); | |
3017 oprintf (d->of, ");\n"); | |
3018 } | |
3019 } | |
3020 } | |
3021 endcounter = d->counter; | |
3022 | |
3023 FOR_ALL_INHERITED_FIELDS (t, f) | |
2660 { | 3024 { |
2661 options_p oo; | 3025 options_p oo; |
2662 const char *dot = "."; | 3026 const char *dot = "."; |
2663 const char *tagid = NULL; | 3027 const char *tagid = NULL; |
2664 int skip_p = 0; | 3028 int skip_p = 0; |
2665 int default_p = 0; | 3029 int default_p = 0; |
2666 int use_param_p = 0; | 3030 const char *fieldlength = NULL; |
2667 char *newval; | 3031 char *newval; |
2668 | 3032 |
2669 d->reorder_fn = NULL; | 3033 d->reorder_fn = NULL; |
2670 for (oo = f->opt; oo; oo = oo->next) | 3034 for (oo = f->opt; oo; oo = oo->next) |
2671 if (strcmp (oo->name, "dot") == 0 | 3035 if (strcmp (oo->name, "dot") == 0 |
2679 else if (strcmp (oo->name, "default") == 0) | 3043 else if (strcmp (oo->name, "default") == 0) |
2680 default_p = 1; | 3044 default_p = 1; |
2681 else if (strcmp (oo->name, "reorder") == 0 | 3045 else if (strcmp (oo->name, "reorder") == 0 |
2682 && oo->kind == OPTION_STRING) | 3046 && oo->kind == OPTION_STRING) |
2683 d->reorder_fn = oo->info.string; | 3047 d->reorder_fn = oo->info.string; |
2684 else if (strncmp (oo->name, "use_param", 9) == 0 | 3048 else if (strcmp (oo->name, "length") == 0 |
2685 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9]))) | 3049 && oo->kind == OPTION_STRING) |
2686 use_param_p = 1; | 3050 fieldlength = oo->info.string; |
2687 | 3051 |
2688 if (skip_p) | 3052 if (skip_p) |
2689 continue; | 3053 continue; |
2690 | 3054 |
2691 if (union_p && tagid) | 3055 if (union_p && tagid) |
2715 else if (union_p && !(default_p || tagid)) | 3079 else if (union_p && !(default_p || tagid)) |
2716 error_at_line (d->line, | 3080 error_at_line (d->line, |
2717 "field `%s' is missing `tag' or `default' option", | 3081 "field `%s' is missing `tag' or `default' option", |
2718 f->name); | 3082 f->name); |
2719 | 3083 |
3084 if (fieldlength) | |
3085 { | |
3086 d->loopcounter = endcounter - lengths_seen--; | |
3087 } | |
3088 | |
2720 d->line = &f->line; | 3089 d->line = &f->line; |
2721 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name); | 3090 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name); |
2722 d->opt = f->opt; | 3091 d->opt = f->opt; |
2723 d->used_length = false; | 3092 d->used_length = false; |
2724 | 3093 d->in_record_p = !union_p; |
2725 if (union_p && use_param_p && d->param == NULL) | 3094 |
2726 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, ""); | 3095 walk_type (f->type, d); |
2727 else | 3096 |
2728 walk_type (f->type, d); | 3097 d->in_record_p = false; |
2729 | 3098 |
2730 free (newval); | 3099 free (newval); |
2731 | 3100 |
2732 if (union_p) | 3101 if (union_p) |
2733 { | 3102 { |
2744 if (union_p && !seen_default_p) | 3113 if (union_p && !seen_default_p) |
2745 { | 3114 { |
2746 oprintf (d->of, "%*sdefault:\n", d->indent, ""); | 3115 oprintf (d->of, "%*sdefault:\n", d->indent, ""); |
2747 oprintf (d->of, "%*s break;\n", d->indent, ""); | 3116 oprintf (d->of, "%*s break;\n", d->indent, ""); |
2748 } | 3117 } |
3118 | |
3119 if (desc && !union_p) | |
3120 { | |
3121 oprintf (d->of, "%*sbreak;\n", d->indent, ""); | |
3122 d->indent -= 2; | |
3123 } | |
2749 if (union_p) | 3124 if (union_p) |
2750 { | 3125 { |
2751 oprintf (d->of, "%*s}\n", d->indent, ""); | 3126 oprintf (d->of, "%*s}\n", d->indent, ""); |
2752 d->indent -= 2; | 3127 d->indent -= 2; |
3128 } | |
3129 else if (desc) | |
3130 { | |
3131 /* Add cases to handle subclasses. */ | |
3132 struct seen_tag *tags = NULL; | |
3133 walk_subclasses (t, d, &tags); | |
3134 | |
3135 /* Ensure that if someone forgets a "tag" option that we don't | |
3136 silent fail to traverse that subclass's fields. */ | |
3137 if (!seen_default_p) | |
3138 { | |
3139 oprintf (d->of, "%*s/* Unrecognized tag value. */\n", | |
3140 d->indent, ""); | |
3141 oprintf (d->of, "%*sdefault: gcc_unreachable (); \n", | |
3142 d->indent, ""); | |
3143 } | |
3144 | |
3145 /* End of the switch statement */ | |
3146 oprintf (d->of, "%*s}\n", d->indent, ""); | |
3147 d->indent -= 2; | |
3148 } | |
3149 if (any_length_seen) | |
3150 { | |
3151 d->indent -= 2; | |
3152 oprintf (d->of, "%*s}\n", d->indent, ""); | |
2753 } | 3153 } |
2754 } | 3154 } |
2755 break; | 3155 break; |
2756 | 3156 |
2757 case TYPE_LANG_STRUCT: | 3157 case TYPE_LANG_STRUCT: |
2766 else | 3166 else |
2767 walk_type (nt, d); | 3167 walk_type (nt, d); |
2768 } | 3168 } |
2769 break; | 3169 break; |
2770 | 3170 |
2771 case TYPE_PARAM_STRUCT: | 3171 case TYPE_USER_STRUCT: |
2772 { | 3172 d->process_field (t, d); |
2773 type_p *oldparam = d->param; | |
2774 | |
2775 d->param = t->u.param_struct.param; | |
2776 walk_type (t->u.param_struct.stru, d); | |
2777 d->param = oldparam; | |
2778 } | |
2779 break; | 3173 break; |
2780 | 3174 |
2781 default: | 3175 case TYPE_NONE: |
3176 case TYPE_UNDEFINED: | |
2782 gcc_unreachable (); | 3177 gcc_unreachable (); |
2783 } | 3178 } |
2784 } | 3179 } |
2785 | 3180 |
2786 /* process_field routine for marking routines. */ | 3181 /* process_field routine for marking routines. */ |
2793 wtd = (const struct write_types_data *) d->cookie; | 3188 wtd = (const struct write_types_data *) d->cookie; |
2794 | 3189 |
2795 switch (f->kind) | 3190 switch (f->kind) |
2796 { | 3191 { |
2797 case TYPE_NONE: | 3192 case TYPE_NONE: |
3193 case TYPE_UNDEFINED: | |
2798 gcc_unreachable (); | 3194 gcc_unreachable (); |
2799 case TYPE_POINTER: | 3195 case TYPE_POINTER: |
2800 oprintf (d->of, "%*s%s (%s%s", d->indent, "", | 3196 oprintf (d->of, "%*s%s (%s%s", d->indent, "", |
2801 wtd->subfield_marker_routine, cast, d->val); | 3197 wtd->subfield_marker_routine, cast, d->val); |
2802 if (wtd->param_prefix) | 3198 if (wtd->param_prefix) |
2803 { | 3199 { |
2804 oprintf (d->of, ", %s", d->prev_val[3]); | 3200 if (f->u.p->kind == TYPE_SCALAR) |
3201 /* The current type is a pointer to a scalar (so not | |
3202 considered like a pointer to instances of user defined | |
3203 types) and we are seeing it; it means we must be even | |
3204 more careful about the second argument of the | |
3205 SUBFIELD_MARKER_ROUTINE call. That argument must | |
3206 always be the instance of the type for which | |
3207 write_func_for_structure was called - this really is | |
3208 what the function SUBFIELD_MARKER_ROUTINE expects. | |
3209 That is, it must be an instance of the ORIG_S type | |
3210 parameter of write_func_for_structure. The convention | |
3211 is that that argument must be "x" in that case (as set | |
3212 by write_func_for_structure). The problem is, we can't | |
3213 count on d->prev_val[3] to be always set to "x" in that | |
3214 case. Sometimes walk_type can set it to something else | |
3215 (to e.g cooperate with write_array when called from | |
3216 write_roots). So let's set it to "x" here then. */ | |
3217 oprintf (d->of, ", x"); | |
3218 else | |
3219 oprintf (d->of, ", %s", d->prev_val[3]); | |
2805 if (d->orig_s) | 3220 if (d->orig_s) |
2806 { | 3221 { |
2807 oprintf (d->of, ", gt_%s_", wtd->param_prefix); | 3222 oprintf (d->of, ", gt_%s_", wtd->param_prefix); |
2808 output_mangled_typename (d->of, d->orig_s); | 3223 output_mangled_typename (d->of, d->orig_s); |
2809 } | 3224 } |
2810 else | 3225 else |
2811 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]); | 3226 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]); |
2812 | |
2813 if (f->u.p->kind == TYPE_PARAM_STRUCT | |
2814 && f->u.p->u.s.line.file != NULL) | |
2815 { | |
2816 oprintf (d->of, ", gt_e_"); | |
2817 output_mangled_typename (d->of, f); | |
2818 } | |
2819 else if (UNION_OR_STRUCT_P (f) && f->u.p->u.s.line.file != NULL) | |
2820 { | |
2821 oprintf (d->of, ", gt_ggc_e_"); | |
2822 output_mangled_typename (d->of, f); | |
2823 } | |
2824 else | |
2825 oprintf (d->of, ", gt_types_enum_last"); | |
2826 } | 3227 } |
2827 oprintf (d->of, ");\n"); | 3228 oprintf (d->of, ");\n"); |
2828 if (d->reorder_fn && wtd->reorder_note_routine) | 3229 if (d->reorder_fn && wtd->reorder_note_routine) |
2829 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "", | 3230 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "", |
2830 wtd->reorder_note_routine, cast, d->val, | 3231 wtd->reorder_note_routine, cast, d->val, |
2833 | 3234 |
2834 case TYPE_STRING: | 3235 case TYPE_STRING: |
2835 case TYPE_STRUCT: | 3236 case TYPE_STRUCT: |
2836 case TYPE_UNION: | 3237 case TYPE_UNION: |
2837 case TYPE_LANG_STRUCT: | 3238 case TYPE_LANG_STRUCT: |
2838 case TYPE_PARAM_STRUCT: | 3239 case TYPE_USER_STRUCT: |
2839 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix); | 3240 if (f->kind == TYPE_USER_STRUCT && !d->in_ptr_field) |
2840 output_mangled_typename (d->of, f); | 3241 { |
2841 oprintf (d->of, " (%s%s);\n", cast, d->val); | 3242 /* If F is a user-defined type and the field is not a |
2842 if (d->reorder_fn && wtd->reorder_note_routine) | 3243 pointer to the type, then we should not generate the |
2843 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "", | 3244 standard pointer-marking code. All we need to do is call |
2844 wtd->reorder_note_routine, cast, d->val, cast, d->val, | 3245 the user-provided marking function to process the fields |
2845 d->reorder_fn); | 3246 of F. */ |
3247 oprintf (d->of, "%*sgt_%sx (&(%s));\n", d->indent, "", wtd->prefix, | |
3248 d->val); | |
3249 } | |
3250 else | |
3251 { | |
3252 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix); | |
3253 output_mangled_typename (d->of, f); | |
3254 oprintf (d->of, " (%s%s);\n", cast, d->val); | |
3255 if (d->reorder_fn && wtd->reorder_note_routine) | |
3256 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "", | |
3257 wtd->reorder_note_routine, cast, d->val, cast, d->val, | |
3258 d->reorder_fn); | |
3259 } | |
2846 break; | 3260 break; |
2847 | 3261 |
2848 case TYPE_SCALAR: | 3262 case TYPE_SCALAR: |
2849 break; | 3263 break; |
2850 | 3264 |
2851 case TYPE_ARRAY: | 3265 case TYPE_ARRAY: |
2852 gcc_unreachable (); | 3266 gcc_unreachable (); |
2853 } | 3267 } |
2854 } | 3268 } |
2855 | 3269 |
2856 /* A subroutine of write_func_for_structure. Write the enum tag for S. */ | |
2857 | |
2858 static void | |
2859 output_type_enum (outf_p of, type_p s) | |
2860 { | |
2861 if (s->kind == TYPE_PARAM_STRUCT && s->u.param_struct.line.file != NULL) | |
2862 { | |
2863 oprintf (of, ", gt_e_"); | |
2864 output_mangled_typename (of, s); | |
2865 } | |
2866 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL) | |
2867 { | |
2868 oprintf (of, ", gt_ggc_e_"); | |
2869 output_mangled_typename (of, s); | |
2870 } | |
2871 else | |
2872 oprintf (of, ", gt_types_enum_last"); | |
2873 } | |
2874 | |
2875 /* Return an output file that is suitable for definitions which can | 3270 /* Return an output file that is suitable for definitions which can |
2876 reference struct S */ | 3271 reference struct S */ |
2877 | 3272 |
2878 static outf_p | 3273 static outf_p |
2879 get_output_file_for_structure (const_type_p s, type_p *param) | 3274 get_output_file_for_structure (const_type_p s) |
2880 { | 3275 { |
2881 const input_file *fn; | 3276 const input_file *fn; |
2882 int i; | 3277 |
2883 | 3278 gcc_assert (union_or_struct_p (s)); |
2884 gcc_assert (UNION_OR_STRUCT_P (s)); | |
2885 fn = s->u.s.line.file; | 3279 fn = s->u.s.line.file; |
2886 | |
2887 /* This is a hack, and not the good kind either. */ | |
2888 for (i = NUM_PARAM - 1; i >= 0; i--) | |
2889 if (param && param[i] && param[i]->kind == TYPE_POINTER | |
2890 && UNION_OR_STRUCT_P (param[i]->u.p)) | |
2891 fn = param[i]->u.p->u.s.line.file; | |
2892 | 3280 |
2893 /* The call to get_output_file_with_visibility may update fn by | 3281 /* The call to get_output_file_with_visibility may update fn by |
2894 caching its result inside, so we need the CONST_CAST. */ | 3282 caching its result inside, so we need the CONST_CAST. */ |
2895 return get_output_file_with_visibility (CONST_CAST (input_file*, fn)); | 3283 return get_output_file_with_visibility (CONST_CAST (input_file*, fn)); |
2896 } | 3284 } |
2897 | 3285 |
2898 /* For S, a structure that's part of ORIG_S, and using parameters | 3286 |
2899 PARAM, write out a routine that: | 3287 /* Returns the specifier keyword for a string or union type S, empty string |
3288 otherwise. */ | |
3289 | |
3290 static const char * | |
3291 get_type_specifier (const type_p s) | |
3292 { | |
3293 if (s->kind == TYPE_STRUCT) | |
3294 return "struct "; | |
3295 else if (s->kind == TYPE_LANG_STRUCT) | |
3296 return get_type_specifier (s->u.s.lang_struct); | |
3297 else if (s->kind == TYPE_UNION) | |
3298 return "union "; | |
3299 return ""; | |
3300 } | |
3301 | |
3302 | |
3303 /* Emits a declaration for type TY (assumed to be a union or a | |
3304 structure) on stream OUT. */ | |
3305 | |
3306 static void | |
3307 write_type_decl (outf_p out, type_p ty) | |
3308 { | |
3309 if (union_or_struct_p (ty)) | |
3310 oprintf (out, "%s%s", get_type_specifier (ty), ty->u.s.tag); | |
3311 else if (ty->kind == TYPE_SCALAR) | |
3312 { | |
3313 if (ty->u.scalar_is_char) | |
3314 oprintf (out, "const char"); | |
3315 else | |
3316 oprintf (out, "void"); | |
3317 } | |
3318 else if (ty->kind == TYPE_POINTER) | |
3319 { | |
3320 write_type_decl (out, ty->u.p); | |
3321 oprintf (out, " *"); | |
3322 } | |
3323 else if (ty->kind == TYPE_ARRAY) | |
3324 { | |
3325 write_type_decl (out, ty->u.a.p); | |
3326 oprintf (out, " *"); | |
3327 } | |
3328 else if (ty->kind == TYPE_STRING) | |
3329 { | |
3330 oprintf (out, "const char *"); | |
3331 } | |
3332 else | |
3333 gcc_unreachable (); | |
3334 } | |
3335 | |
3336 | |
3337 /* Write on OF the name of the marker function for structure S. PREFIX | |
3338 is the prefix to use (to distinguish ggc from pch markers). */ | |
3339 | |
3340 static void | |
3341 write_marker_function_name (outf_p of, type_p s, const char *prefix) | |
3342 { | |
3343 if (union_or_struct_p (s)) | |
3344 { | |
3345 const char *id_for_tag = filter_type_name (s->u.s.tag); | |
3346 oprintf (of, "gt_%sx_%s", prefix, id_for_tag); | |
3347 if (id_for_tag != s->u.s.tag) | |
3348 free (CONST_CAST (char *, id_for_tag)); | |
3349 } | |
3350 else | |
3351 gcc_unreachable (); | |
3352 } | |
3353 | |
3354 /* Write on OF a user-callable routine to act as an entry point for | |
3355 the marking routine for S, generated by write_func_for_structure. | |
3356 WTD distinguishes between ggc and pch markers. */ | |
3357 | |
3358 static void | |
3359 write_user_func_for_structure_ptr (outf_p of, type_p s, const write_types_data *wtd) | |
3360 { | |
3361 gcc_assert (union_or_struct_p (s)); | |
3362 | |
3363 type_p alias_of = NULL; | |
3364 for (options_p opt = s->u.s.opt; opt; opt = opt->next) | |
3365 if (strcmp (opt->name, "ptr_alias") == 0) | |
3366 { | |
3367 /* ALIAS_OF is set if ORIG_S is marked "ptr_alias". This means that | |
3368 we do not generate marking code for ORIG_S here. Instead, a | |
3369 forwarder #define in gtype-desc.h will cause every call to its | |
3370 marker to call the target of this alias. | |
3371 | |
3372 However, we still want to create a user entry code for the | |
3373 aliased type. So, if ALIAS_OF is set, we only generate the | |
3374 user-callable marker function. */ | |
3375 alias_of = opt->info.type; | |
3376 break; | |
3377 } | |
3378 | |
3379 DBGPRINTF ("write_user_func_for_structure_ptr: %s %s", s->u.s.tag, | |
3380 wtd->prefix); | |
3381 | |
3382 /* Only write the function once. */ | |
3383 if (s->u.s.wrote_user_func_for_ptr[wtd->kind]) | |
3384 return; | |
3385 s->u.s.wrote_user_func_for_ptr[wtd->kind] = true; | |
3386 | |
3387 oprintf (of, "\nvoid\n"); | |
3388 oprintf (of, "gt_%sx (", wtd->prefix); | |
3389 write_type_decl (of, s); | |
3390 oprintf (of, " *& x)\n"); | |
3391 oprintf (of, "{\n"); | |
3392 oprintf (of, " if (x)\n "); | |
3393 write_marker_function_name (of, | |
3394 alias_of ? alias_of : get_ultimate_base_class (s), | |
3395 wtd->prefix); | |
3396 oprintf (of, " ((void *) x);\n"); | |
3397 oprintf (of, "}\n"); | |
3398 } | |
3399 | |
3400 | |
3401 /* Write a function to mark all the fields of type S on OF. PREFIX | |
3402 and D are as in write_user_marking_functions. */ | |
3403 | |
3404 static void | |
3405 write_user_func_for_structure_body (type_p s, const char *prefix, | |
3406 struct walk_type_data *d) | |
3407 { | |
3408 oprintf (d->of, "\nvoid\n"); | |
3409 oprintf (d->of, "gt_%sx (", prefix); | |
3410 write_type_decl (d->of, s); | |
3411 oprintf (d->of, "& x_r ATTRIBUTE_UNUSED)\n"); | |
3412 oprintf (d->of, "{\n"); | |
3413 oprintf (d->of, " "); | |
3414 write_type_decl (d->of, s); | |
3415 oprintf (d->of, " * ATTRIBUTE_UNUSED x = &x_r;\n"); | |
3416 d->val = "(*x)"; | |
3417 d->indent = 2; | |
3418 walk_type (s, d); | |
3419 oprintf (d->of, "}\n"); | |
3420 } | |
3421 | |
3422 /* Emit the user-callable functions needed to mark all the types used | |
3423 by the user structure S. PREFIX is the prefix to use to | |
3424 distinguish ggc and pch markers. D contains data needed to pass to | |
3425 walk_type when traversing the fields of a type. | |
3426 | |
3427 For every type T referenced by S, two routines are generated: one | |
3428 that takes 'T *', marks the pointer and calls the second routine, | |
3429 which just marks the fields of T. */ | |
3430 | |
3431 static void | |
3432 write_user_marking_functions (type_p s, | |
3433 const write_types_data *w, | |
3434 struct walk_type_data *d) | |
3435 { | |
3436 gcc_assert (s->kind == TYPE_USER_STRUCT); | |
3437 | |
3438 for (pair_p fld = s->u.s.fields; fld; fld = fld->next) | |
3439 { | |
3440 type_p fld_type = fld->type; | |
3441 if (fld_type->kind == TYPE_POINTER) | |
3442 { | |
3443 type_p pointed_to_type = fld_type->u.p; | |
3444 if (union_or_struct_p (pointed_to_type)) | |
3445 write_user_func_for_structure_ptr (d->of, pointed_to_type, w); | |
3446 } | |
3447 else if (union_or_struct_p (fld_type)) | |
3448 write_user_func_for_structure_body (fld_type, w->prefix, d); | |
3449 } | |
3450 } | |
3451 | |
3452 | |
3453 /* For S, a structure that's part of ORIG_S write out a routine that: | |
2900 - Takes a parameter, a void * but actually of type *S | 3454 - Takes a parameter, a void * but actually of type *S |
2901 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each | 3455 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each |
2902 field of S or its substructures and (in some cases) things | 3456 field of S or its substructures and (in some cases) things |
2903 that are pointed to by S. | 3457 that are pointed to by S. */ |
2904 */ | |
2905 | 3458 |
2906 static void | 3459 static void |
2907 write_func_for_structure (type_p orig_s, type_p s, type_p *param, | 3460 write_func_for_structure (type_p orig_s, type_p s, |
2908 const struct write_types_data *wtd) | 3461 const struct write_types_data *wtd) |
2909 { | 3462 { |
2910 const char *chain_next = NULL; | 3463 const char *chain_next = NULL; |
2911 const char *chain_prev = NULL; | 3464 const char *chain_prev = NULL; |
2912 const char *chain_circular = NULL; | 3465 const char *chain_circular = NULL; |
2913 const char *mark_hook_name = NULL; | |
2914 options_p opt; | 3466 options_p opt; |
2915 struct walk_type_data d; | 3467 struct walk_type_data d; |
2916 | 3468 |
3469 if (s->u.s.base_class) | |
3470 { | |
3471 /* Verify that the base class has a "desc", since otherwise | |
3472 the traversal hooks there won't attempt to visit fields of | |
3473 subclasses such as this one. */ | |
3474 const_type_p ubc = get_ultimate_base_class (s); | |
3475 if ((!opts_have (ubc->u.s.opt, "user") | |
3476 && !opts_have (ubc->u.s.opt, "desc"))) | |
3477 error_at_line (&s->u.s.line, | |
3478 ("'%s' is a subclass of non-GTY(user) GTY class '%s'" | |
3479 ", but '%s' lacks a discriminator 'desc' option"), | |
3480 s->u.s.tag, ubc->u.s.tag, ubc->u.s.tag); | |
3481 | |
3482 /* Don't write fns for subclasses, only for the ultimate base class | |
3483 within an inheritance hierarchy. */ | |
3484 return; | |
3485 } | |
3486 | |
2917 memset (&d, 0, sizeof (d)); | 3487 memset (&d, 0, sizeof (d)); |
2918 d.of = get_output_file_for_structure (s, param); | 3488 d.of = get_output_file_for_structure (s); |
3489 | |
3490 bool for_user = false; | |
2919 for (opt = s->u.s.opt; opt; opt = opt->next) | 3491 for (opt = s->u.s.opt; opt; opt = opt->next) |
2920 if (strcmp (opt->name, "chain_next") == 0 | 3492 if (strcmp (opt->name, "chain_next") == 0 |
2921 && opt->kind == OPTION_STRING) | 3493 && opt->kind == OPTION_STRING) |
2922 chain_next = opt->info.string; | 3494 chain_next = opt->info.string; |
2923 else if (strcmp (opt->name, "chain_prev") == 0 | 3495 else if (strcmp (opt->name, "chain_prev") == 0 |
2924 && opt->kind == OPTION_STRING) | 3496 && opt->kind == OPTION_STRING) |
2925 chain_prev = opt->info.string; | 3497 chain_prev = opt->info.string; |
2926 else if (strcmp (opt->name, "chain_circular") == 0 | 3498 else if (strcmp (opt->name, "chain_circular") == 0 |
2927 && opt->kind == OPTION_STRING) | 3499 && opt->kind == OPTION_STRING) |
2928 chain_circular = opt->info.string; | 3500 chain_circular = opt->info.string; |
2929 else if (strcmp (opt->name, "mark_hook") == 0 | 3501 else if (strcmp (opt->name, "for_user") == 0) |
2930 && opt->kind == OPTION_STRING) | 3502 for_user = true; |
2931 mark_hook_name = opt->info.string; | |
2932 if (chain_prev != NULL && chain_next == NULL) | 3503 if (chain_prev != NULL && chain_next == NULL) |
2933 error_at_line (&s->u.s.line, "chain_prev without chain_next"); | 3504 error_at_line (&s->u.s.line, "chain_prev without chain_next"); |
2934 if (chain_circular != NULL && chain_next != NULL) | 3505 if (chain_circular != NULL && chain_next != NULL) |
2935 error_at_line (&s->u.s.line, "chain_circular with chain_next"); | 3506 error_at_line (&s->u.s.line, "chain_circular with chain_next"); |
2936 if (chain_circular != NULL) | 3507 if (chain_circular != NULL) |
2940 d.cookie = wtd; | 3511 d.cookie = wtd; |
2941 d.orig_s = orig_s; | 3512 d.orig_s = orig_s; |
2942 d.opt = s->u.s.opt; | 3513 d.opt = s->u.s.opt; |
2943 d.line = &s->u.s.line; | 3514 d.line = &s->u.s.line; |
2944 d.bitmap = s->u.s.bitmap; | 3515 d.bitmap = s->u.s.bitmap; |
2945 d.param = param; | |
2946 d.prev_val[0] = "*x"; | 3516 d.prev_val[0] = "*x"; |
2947 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */ | 3517 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */ |
2948 d.prev_val[3] = "x"; | 3518 d.prev_val[3] = "x"; |
2949 d.val = "(*x)"; | 3519 d.val = "(*x)"; |
3520 d.have_this_obj = false; | |
2950 | 3521 |
2951 oprintf (d.of, "\n"); | 3522 oprintf (d.of, "\n"); |
2952 oprintf (d.of, "void\n"); | 3523 oprintf (d.of, "void\n"); |
2953 if (param == NULL) | 3524 write_marker_function_name (d.of, orig_s, wtd->prefix); |
2954 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag); | |
2955 else | |
2956 { | |
2957 oprintf (d.of, "gt_%s_", wtd->prefix); | |
2958 output_mangled_typename (d.of, orig_s); | |
2959 } | |
2960 oprintf (d.of, " (void *x_p)\n"); | 3525 oprintf (d.of, " (void *x_p)\n"); |
2961 oprintf (d.of, "{\n"); | 3526 oprintf (d.of, "{\n "); |
2962 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n", | 3527 write_type_decl (d.of, s); |
2963 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag, | 3528 oprintf (d.of, " * %sx = (", chain_next == NULL ? "const " : ""); |
2964 chain_next == NULL ? "const " : "", | 3529 write_type_decl (d.of, s); |
2965 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); | 3530 oprintf (d.of, " *)x_p;\n"); |
2966 if (chain_next != NULL) | 3531 if (chain_next != NULL) |
2967 oprintf (d.of, " %s %s * xlimit = x;\n", | 3532 { |
2968 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); | 3533 /* TYPE_USER_STRUCTs should not occur here. These structures |
3534 are completely handled by user code. */ | |
3535 gcc_assert (orig_s->kind != TYPE_USER_STRUCT); | |
3536 | |
3537 oprintf (d.of, " "); | |
3538 write_type_decl (d.of, s); | |
3539 oprintf (d.of, " * xlimit = x;\n"); | |
3540 } | |
2969 if (chain_next == NULL) | 3541 if (chain_next == NULL) |
2970 { | 3542 { |
2971 oprintf (d.of, " if (%s (x", wtd->marker_routine); | 3543 oprintf (d.of, " if (%s (x", wtd->marker_routine); |
2972 if (wtd->param_prefix) | 3544 if (wtd->param_prefix) |
2973 { | 3545 { |
2974 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix); | 3546 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix); |
2975 output_mangled_typename (d.of, orig_s); | 3547 output_mangled_typename (d.of, orig_s); |
2976 output_type_enum (d.of, orig_s); | |
2977 } | 3548 } |
2978 oprintf (d.of, "))\n"); | 3549 oprintf (d.of, "))\n"); |
2979 } | 3550 } |
2980 else | 3551 else |
2981 { | 3552 { |
2985 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine); | 3556 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine); |
2986 if (wtd->param_prefix) | 3557 if (wtd->param_prefix) |
2987 { | 3558 { |
2988 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix); | 3559 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix); |
2989 output_mangled_typename (d.of, orig_s); | 3560 output_mangled_typename (d.of, orig_s); |
2990 output_type_enum (d.of, orig_s); | |
2991 } | 3561 } |
2992 oprintf (d.of, "))\n"); | 3562 oprintf (d.of, "))\n"); |
2993 if (chain_circular != NULL) | 3563 if (chain_circular != NULL) |
2994 oprintf (d.of, " return;\n do\n"); | 3564 oprintf (d.of, " return;\n do\n"); |
2995 if (mark_hook_name && !wtd->skip_hooks) | 3565 |
2996 { | |
2997 oprintf (d.of, " {\n"); | |
2998 oprintf (d.of, " %s (xlimit);\n ", mark_hook_name); | |
2999 } | |
3000 oprintf (d.of, " xlimit = ("); | 3566 oprintf (d.of, " xlimit = ("); |
3001 d.prev_val[2] = "*xlimit"; | 3567 d.prev_val[2] = "*xlimit"; |
3002 output_escaped_param (&d, chain_next, "chain_next"); | 3568 output_escaped_param (&d, chain_next, "chain_next"); |
3003 oprintf (d.of, ");\n"); | 3569 oprintf (d.of, ");\n"); |
3004 if (mark_hook_name && !wtd->skip_hooks) | |
3005 oprintf (d.of, " }\n"); | |
3006 if (chain_prev != NULL) | 3570 if (chain_prev != NULL) |
3007 { | 3571 { |
3008 oprintf (d.of, " if (x != xlimit)\n"); | 3572 oprintf (d.of, " if (x != xlimit)\n"); |
3009 oprintf (d.of, " for (;;)\n"); | 3573 oprintf (d.of, " for (;;)\n"); |
3010 oprintf (d.of, " {\n"); | 3574 oprintf (d.of, " {\n"); |
3019 oprintf (d.of, " (void) %s (xprev", wtd->marker_routine); | 3583 oprintf (d.of, " (void) %s (xprev", wtd->marker_routine); |
3020 if (wtd->param_prefix) | 3584 if (wtd->param_prefix) |
3021 { | 3585 { |
3022 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix); | 3586 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix); |
3023 output_mangled_typename (d.of, orig_s); | 3587 output_mangled_typename (d.of, orig_s); |
3024 output_type_enum (d.of, orig_s); | |
3025 } | 3588 } |
3026 oprintf (d.of, ");\n"); | 3589 oprintf (d.of, ");\n"); |
3027 oprintf (d.of, " }\n"); | 3590 oprintf (d.of, " }\n"); |
3028 } | 3591 } |
3029 if (chain_circular != NULL) | 3592 if (chain_circular != NULL) |
3031 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine); | 3594 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine); |
3032 if (wtd->param_prefix) | 3595 if (wtd->param_prefix) |
3033 { | 3596 { |
3034 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix); | 3597 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix); |
3035 output_mangled_typename (d.of, orig_s); | 3598 output_mangled_typename (d.of, orig_s); |
3036 output_type_enum (d.of, orig_s); | |
3037 } | 3599 } |
3038 oprintf (d.of, "));\n"); | 3600 oprintf (d.of, "));\n"); |
3039 if (mark_hook_name && !wtd->skip_hooks) | |
3040 oprintf (d.of, " %s (xlimit);\n", mark_hook_name); | |
3041 oprintf (d.of, " do\n"); | 3601 oprintf (d.of, " do\n"); |
3042 } | 3602 } |
3043 else | 3603 else |
3044 oprintf (d.of, " while (x != xlimit)\n"); | 3604 oprintf (d.of, " while (x != xlimit)\n"); |
3045 } | 3605 } |
3046 oprintf (d.of, " {\n"); | 3606 oprintf (d.of, " {\n"); |
3047 if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks) | 3607 |
3048 { | |
3049 oprintf (d.of, " %s (x);\n", mark_hook_name); | |
3050 } | |
3051 d.prev_val[2] = "*x"; | 3608 d.prev_val[2] = "*x"; |
3052 d.indent = 6; | 3609 d.indent = 6; |
3053 walk_type (s, &d); | 3610 if (orig_s->kind != TYPE_USER_STRUCT) |
3611 walk_type (s, &d); | |
3612 else | |
3613 { | |
3614 /* User structures have no fields to walk. Simply generate a call | |
3615 to the user-provided structure marker. */ | |
3616 oprintf (d.of, "%*sgt_%sx (x);\n", d.indent, "", wtd->prefix); | |
3617 } | |
3054 | 3618 |
3055 if (chain_next != NULL) | 3619 if (chain_next != NULL) |
3056 { | 3620 { |
3057 oprintf (d.of, " x = ("); | 3621 oprintf (d.of, " x = ("); |
3058 output_escaped_param (&d, chain_next, "chain_next"); | 3622 output_escaped_param (&d, chain_next, "chain_next"); |
3061 | 3625 |
3062 oprintf (d.of, " }\n"); | 3626 oprintf (d.of, " }\n"); |
3063 if (chain_circular != NULL) | 3627 if (chain_circular != NULL) |
3064 oprintf (d.of, " while (x != xlimit);\n"); | 3628 oprintf (d.of, " while (x != xlimit);\n"); |
3065 oprintf (d.of, "}\n"); | 3629 oprintf (d.of, "}\n"); |
3066 } | 3630 |
3631 if (orig_s->kind == TYPE_USER_STRUCT) | |
3632 write_user_marking_functions (orig_s, wtd, &d); | |
3633 | |
3634 if (for_user) | |
3635 { | |
3636 write_user_func_for_structure_body (orig_s, wtd->prefix, &d); | |
3637 write_user_func_for_structure_ptr (d.of, orig_s, wtd); | |
3638 } | |
3639 } | |
3640 | |
3067 | 3641 |
3068 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */ | 3642 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */ |
3069 | 3643 |
3070 static void | 3644 static void |
3071 write_types (outf_p output_header, type_p structures, type_p param_structs, | 3645 write_types (outf_p output_header, type_p structures, |
3072 const struct write_types_data *wtd) | 3646 const struct write_types_data *wtd) |
3073 { | 3647 { |
3074 int nbfun = 0; /* Count the emitted functions. */ | 3648 int nbfun = 0; /* Count the emitted functions. */ |
3075 type_p s; | 3649 type_p s; |
3076 | 3650 |
3077 oprintf (output_header, "\n/* %s*/\n", wtd->comment); | 3651 oprintf (output_header, "\n/* %s*/\n", wtd->comment); |
3652 | |
3078 /* We first emit the macros and the declarations. Functions' code is | 3653 /* We first emit the macros and the declarations. Functions' code is |
3079 emitted afterwards. This is needed in plugin mode. */ | 3654 emitted afterwards. This is needed in plugin mode. */ |
3080 oprintf (output_header, "/* macros and declarations */\n"); | 3655 oprintf (output_header, "/* Macros and declarations. */\n"); |
3081 for (s = structures; s; s = s->next) | 3656 for (s = structures; s; s = s->next) |
3082 if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO) | 3657 /* Do not emit handlers for derived classes; we only ever deal with |
3658 the ultimate base class within an inheritance hierarchy. */ | |
3659 if ((s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO) | |
3660 && !s->u.s.base_class) | |
3083 { | 3661 { |
3084 options_p opt; | 3662 options_p opt; |
3085 | 3663 |
3086 if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL) | 3664 if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL) |
3087 continue; | 3665 continue; |
3666 | |
3667 const char *s_id_for_tag = filter_type_name (s->u.s.tag); | |
3088 | 3668 |
3089 oprintf (output_header, "#define gt_%s_", wtd->prefix); | 3669 oprintf (output_header, "#define gt_%s_", wtd->prefix); |
3090 output_mangled_typename (output_header, s); | 3670 output_mangled_typename (output_header, s); |
3091 oprintf (output_header, "(X) do { \\\n"); | 3671 oprintf (output_header, "(X) do { \\\n"); |
3092 oprintf (output_header, | 3672 oprintf (output_header, |
3093 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix, | 3673 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix, |
3094 s->u.s.tag); | 3674 s_id_for_tag); |
3095 oprintf (output_header, " } while (0)\n"); | 3675 oprintf (output_header, " } while (0)\n"); |
3096 | 3676 |
3097 for (opt = s->u.s.opt; opt; opt = opt->next) | 3677 for (opt = s->u.s.opt; opt; opt = opt->next) |
3098 if (strcmp (opt->name, "ptr_alias") == 0 | 3678 if (strcmp (opt->name, "ptr_alias") == 0 |
3099 && opt->kind == OPTION_TYPE) | 3679 && opt->kind == OPTION_TYPE) |
3100 { | 3680 { |
3101 const_type_p const t = (const_type_p) opt->info.type; | 3681 const_type_p const t = (const_type_p) opt->info.type; |
3102 if (t->kind == TYPE_STRUCT | 3682 if (t->kind == TYPE_STRUCT |
3103 || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT) | 3683 || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT) |
3104 oprintf (output_header, | 3684 { |
3105 "#define gt_%sx_%s gt_%sx_%s\n", | 3685 const char *t_id_for_tag = filter_type_name (t->u.s.tag); |
3106 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag); | 3686 oprintf (output_header, |
3687 "#define gt_%sx_%s gt_%sx_%s\n", | |
3688 wtd->prefix, s->u.s.tag, wtd->prefix, t_id_for_tag); | |
3689 if (t_id_for_tag != t->u.s.tag) | |
3690 free (CONST_CAST (char *, t_id_for_tag)); | |
3691 } | |
3107 else | 3692 else |
3108 error_at_line (&s->u.s.line, | 3693 error_at_line (&s->u.s.line, |
3109 "structure alias is not a structure"); | 3694 "structure alias is not a structure"); |
3110 break; | 3695 break; |
3111 } | 3696 } |
3113 continue; | 3698 continue; |
3114 | 3699 |
3115 /* Declare the marker procedure only once. */ | 3700 /* Declare the marker procedure only once. */ |
3116 oprintf (output_header, | 3701 oprintf (output_header, |
3117 "extern void gt_%sx_%s (void *);\n", | 3702 "extern void gt_%sx_%s (void *);\n", |
3118 wtd->prefix, s->u.s.tag); | 3703 wtd->prefix, s_id_for_tag); |
3704 | |
3705 if (s_id_for_tag != s->u.s.tag) | |
3706 free (CONST_CAST (char *, s_id_for_tag)); | |
3119 | 3707 |
3120 if (s->u.s.line.file == NULL) | 3708 if (s->u.s.line.file == NULL) |
3121 { | |
3122 fprintf (stderr, "warning: structure `%s' used but not defined\n", | |
3123 s->u.s.tag); | |
3124 continue; | |
3125 } | |
3126 } | |
3127 | |
3128 for (s = param_structs; s; s = s->next) | |
3129 if (s->gc_used == GC_POINTED_TO) | |
3130 { | |
3131 type_p stru = s->u.param_struct.stru; | |
3132 | |
3133 /* Declare the marker procedure. */ | |
3134 oprintf (output_header, "extern void gt_%s_", wtd->prefix); | |
3135 output_mangled_typename (output_header, s); | |
3136 oprintf (output_header, " (void *);\n"); | |
3137 | |
3138 if (stru->u.s.line.file == NULL) | |
3139 { | 3709 { |
3140 fprintf (stderr, "warning: structure `%s' used but not defined\n", | 3710 fprintf (stderr, "warning: structure `%s' used but not defined\n", |
3141 s->u.s.tag); | 3711 s->u.s.tag); |
3142 continue; | 3712 continue; |
3143 } | 3713 } |
3164 for (ss = s->u.s.lang_struct; ss; ss = ss->next) | 3734 for (ss = s->u.s.lang_struct; ss; ss = ss->next) |
3165 { | 3735 { |
3166 nbfun++; | 3736 nbfun++; |
3167 DBGPRINTF ("writing func #%d lang_struct ss @ %p '%s'", | 3737 DBGPRINTF ("writing func #%d lang_struct ss @ %p '%s'", |
3168 nbfun, (void*) ss, ss->u.s.tag); | 3738 nbfun, (void*) ss, ss->u.s.tag); |
3169 write_func_for_structure (s, ss, NULL, wtd); | 3739 write_func_for_structure (s, ss, wtd); |
3170 } | 3740 } |
3171 } | 3741 } |
3172 else | 3742 else |
3173 { | 3743 { |
3174 nbfun++; | 3744 nbfun++; |
3175 DBGPRINTF ("writing func #%d struct s @ %p '%s'", | 3745 DBGPRINTF ("writing func #%d struct s @ %p '%s'", |
3176 nbfun, (void*) s, s->u.s.tag); | 3746 nbfun, (void*) s, s->u.s.tag); |
3177 write_func_for_structure (s, s, NULL, wtd); | 3747 write_func_for_structure (s, s, wtd); |
3178 } | 3748 } |
3179 } | 3749 } |
3180 else | 3750 else |
3181 { | 3751 { |
3182 /* Structure s is not possibly pointed to, so can be ignored. */ | 3752 /* Structure s is not possibly pointed to, so can be ignored. */ |
3183 DBGPRINTF ("ignored s @ %p '%s' gc_used#%d", | 3753 DBGPRINTF ("ignored s @ %p '%s' gc_used#%d", |
3184 (void*)s, s->u.s.tag, | 3754 (void*)s, s->u.s.tag, |
3185 (int) s->gc_used); | 3755 (int) s->gc_used); |
3186 } | 3756 } |
3187 | 3757 |
3188 for (s = param_structs; s; s = s->next) | |
3189 if (s->gc_used == GC_POINTED_TO) | |
3190 { | |
3191 type_p *param = s->u.param_struct.param; | |
3192 type_p stru = s->u.param_struct.stru; | |
3193 if (stru->u.s.line.file == NULL) | |
3194 continue; | |
3195 if (stru->kind == TYPE_LANG_STRUCT) | |
3196 { | |
3197 type_p ss; | |
3198 for (ss = stru->u.s.lang_struct; ss; ss = ss->next) | |
3199 { | |
3200 nbfun++; | |
3201 DBGPRINTF ("writing func #%d param lang_struct ss @ %p '%s'", | |
3202 nbfun, (void*) ss, ss->u.s.tag); | |
3203 write_func_for_structure (s, ss, param, wtd); | |
3204 } | |
3205 } | |
3206 else | |
3207 { | |
3208 nbfun++; | |
3209 DBGPRINTF ("writing func #%d param struct s @ %p stru @ %p '%s'", | |
3210 nbfun, (void*) s, | |
3211 (void*) stru, stru->u.s.tag); | |
3212 write_func_for_structure (s, stru, param, wtd); | |
3213 } | |
3214 } | |
3215 else | |
3216 { | |
3217 /* Param structure s is not pointed to, so should be ignored. */ | |
3218 DBGPRINTF ("ignored s @ %p", (void*)s); | |
3219 } | |
3220 if (verbosity_level >= 2) | 3758 if (verbosity_level >= 2) |
3221 printf ("%s emitted %d routines for %s\n", | 3759 printf ("%s emitted %d routines for %s\n", |
3222 progname, nbfun, wtd->comment); | 3760 progname, nbfun, wtd->comment); |
3223 } | 3761 } |
3224 | 3762 |
3225 static const struct write_types_data ggc_wtd = { | 3763 static const struct write_types_data ggc_wtd = { |
3226 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL, | 3764 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL, |
3227 "GC marker procedures. ", | 3765 "GC marker procedures. ", |
3228 FALSE | 3766 WTK_GGC |
3229 }; | 3767 }; |
3230 | 3768 |
3231 static const struct write_types_data pch_wtd = { | 3769 static const struct write_types_data pch_wtd = { |
3232 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object", | 3770 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object", |
3233 "gt_pch_note_reorder", | 3771 "gt_pch_note_reorder", |
3234 "PCH type-walking procedures. ", | 3772 "PCH type-walking procedures. ", |
3235 TRUE | 3773 WTK_PCH |
3236 }; | 3774 }; |
3237 | 3775 |
3238 /* Write out the local pointer-walking routines. */ | 3776 /* Write out the local pointer-walking routines. */ |
3239 | 3777 |
3240 /* process_field routine for local pointer-walking. */ | 3778 /* process_field routine for local pointer-walking for user-callable |
3779 routines. The difference between this and | |
3780 write_types_local_process_field is that, in this case, we do not | |
3781 need to check whether the given pointer matches the address of the | |
3782 parent structure. This check was already generated by the call | |
3783 to gt_pch_nx in the main gt_pch_p_*() function that is calling | |
3784 this code. */ | |
3241 | 3785 |
3242 static void | 3786 static void |
3243 write_types_local_process_field (type_p f, const struct walk_type_data *d) | 3787 write_types_local_user_process_field (type_p f, const struct walk_type_data *d) |
3244 { | 3788 { |
3245 switch (f->kind) | 3789 switch (f->kind) |
3246 { | 3790 { |
3247 case TYPE_POINTER: | 3791 case TYPE_POINTER: |
3248 case TYPE_STRUCT: | 3792 case TYPE_STRUCT: |
3249 case TYPE_UNION: | 3793 case TYPE_UNION: |
3250 case TYPE_LANG_STRUCT: | 3794 case TYPE_LANG_STRUCT: |
3251 case TYPE_PARAM_STRUCT: | 3795 case TYPE_STRING: |
3796 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val); | |
3797 break; | |
3798 | |
3799 case TYPE_USER_STRUCT: | |
3800 if (d->in_ptr_field) | |
3801 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val); | |
3802 else | |
3803 oprintf (d->of, "%*s gt_pch_nx (&(%s), op, cookie);\n", | |
3804 d->indent, "", d->val); | |
3805 break; | |
3806 | |
3807 case TYPE_SCALAR: | |
3808 break; | |
3809 | |
3810 case TYPE_ARRAY: | |
3811 case TYPE_NONE: | |
3812 case TYPE_UNDEFINED: | |
3813 gcc_unreachable (); | |
3814 } | |
3815 } | |
3816 | |
3817 | |
3818 /* Write a function to PCH walk all the fields of type S on OF. | |
3819 D contains data needed by walk_type to recurse into the fields of S. */ | |
3820 | |
3821 static void | |
3822 write_pch_user_walking_for_structure_body (type_p s, struct walk_type_data *d) | |
3823 { | |
3824 oprintf (d->of, "\nvoid\n"); | |
3825 oprintf (d->of, "gt_pch_nx ("); | |
3826 write_type_decl (d->of, s); | |
3827 oprintf (d->of, "* x ATTRIBUTE_UNUSED,\n" | |
3828 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n" | |
3829 "\tATTRIBUTE_UNUSED void *cookie)\n"); | |
3830 oprintf (d->of, "{\n"); | |
3831 d->val = "(*x)"; | |
3832 d->indent = 2; | |
3833 d->process_field = write_types_local_user_process_field; | |
3834 walk_type (s, d); | |
3835 oprintf (d->of, "}\n"); | |
3836 } | |
3837 | |
3838 | |
3839 /* Emit the user-callable functions needed to mark all the types used | |
3840 by the user structure S. PREFIX is the prefix to use to | |
3841 distinguish ggc and pch markers. CHAIN_NEXT is set if S has the | |
3842 chain_next option defined. D contains data needed to pass to | |
3843 walk_type when traversing the fields of a type. | |
3844 | |
3845 For every type T referenced by S, two routines are generated: one | |
3846 that takes 'T *', marks the pointer and calls the second routine, | |
3847 which just marks the fields of T. */ | |
3848 | |
3849 static void | |
3850 write_pch_user_walking_functions (type_p s, struct walk_type_data *d) | |
3851 { | |
3852 gcc_assert (s->kind == TYPE_USER_STRUCT); | |
3853 | |
3854 for (pair_p fld = s->u.s.fields; fld; fld = fld->next) | |
3855 { | |
3856 type_p fld_type = fld->type; | |
3857 if (union_or_struct_p (fld_type)) | |
3858 write_pch_user_walking_for_structure_body (fld_type, d); | |
3859 } | |
3860 } | |
3861 | |
3862 | |
3863 /* process_field routine for local pointer-walking. */ | |
3864 | |
3865 static void | |
3866 write_types_local_process_field (type_p f, const struct walk_type_data *d) | |
3867 { | |
3868 gcc_assert (d->have_this_obj); | |
3869 switch (f->kind) | |
3870 { | |
3871 case TYPE_POINTER: | |
3872 case TYPE_STRUCT: | |
3873 case TYPE_UNION: | |
3874 case TYPE_LANG_STRUCT: | |
3252 case TYPE_STRING: | 3875 case TYPE_STRING: |
3253 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "", | 3876 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "", |
3254 d->prev_val[3]); | 3877 d->prev_val[3]); |
3255 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val); | 3878 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val); |
3256 break; | 3879 break; |
3257 | 3880 |
3881 case TYPE_USER_STRUCT: | |
3882 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "", | |
3883 d->prev_val[3]); | |
3884 if (d->in_ptr_field) | |
3885 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val); | |
3886 else | |
3887 oprintf (d->of, "%*s gt_pch_nx (&(%s), op, cookie);\n", | |
3888 d->indent, "", d->val); | |
3889 break; | |
3890 | |
3258 case TYPE_SCALAR: | 3891 case TYPE_SCALAR: |
3259 break; | 3892 break; |
3260 | 3893 |
3261 default: | 3894 case TYPE_ARRAY: |
3895 case TYPE_NONE: | |
3896 case TYPE_UNDEFINED: | |
3262 gcc_unreachable (); | 3897 gcc_unreachable (); |
3263 } | 3898 } |
3264 } | 3899 } |
3900 | |
3265 | 3901 |
3266 /* For S, a structure that's part of ORIG_S, and using parameters | 3902 /* For S, a structure that's part of ORIG_S, and using parameters |
3267 PARAM, write out a routine that: | 3903 PARAM, write out a routine that: |
3268 - Is of type gt_note_pointers | 3904 - Is of type gt_note_pointers |
3269 - Calls PROCESS_FIELD on each field of S or its substructures. | 3905 - Calls PROCESS_FIELD on each field of S or its substructures. |
3270 */ | 3906 */ |
3271 | 3907 |
3272 static void | 3908 static void |
3273 write_local_func_for_structure (const_type_p orig_s, type_p s, type_p *param) | 3909 write_local_func_for_structure (const_type_p orig_s, type_p s) |
3274 { | 3910 { |
3275 struct walk_type_data d; | 3911 struct walk_type_data d; |
3276 | 3912 |
3913 /* Don't write fns for subclasses, only for the ultimate base class | |
3914 within an inheritance hierarchy. */ | |
3915 if (s->u.s.base_class) | |
3916 return; | |
3917 | |
3277 memset (&d, 0, sizeof (d)); | 3918 memset (&d, 0, sizeof (d)); |
3278 d.of = get_output_file_for_structure (s, param); | 3919 d.of = get_output_file_for_structure (s); |
3279 d.process_field = write_types_local_process_field; | 3920 d.process_field = write_types_local_process_field; |
3280 d.opt = s->u.s.opt; | 3921 d.opt = s->u.s.opt; |
3281 d.line = &s->u.s.line; | 3922 d.line = &s->u.s.line; |
3282 d.bitmap = s->u.s.bitmap; | 3923 d.bitmap = s->u.s.bitmap; |
3283 d.param = param; | |
3284 d.prev_val[0] = d.prev_val[2] = "*x"; | 3924 d.prev_val[0] = d.prev_val[2] = "*x"; |
3285 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */ | 3925 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */ |
3286 d.prev_val[3] = "x"; | 3926 d.prev_val[3] = "x"; |
3287 d.val = "(*x)"; | 3927 d.val = "(*x)"; |
3288 d.fn_wants_lvalue = true; | 3928 d.fn_wants_lvalue = true; |
3294 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n" | 3934 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n" |
3295 "\tvoid *x_p,\n" | 3935 "\tvoid *x_p,\n" |
3296 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n" | 3936 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n" |
3297 "\tATTRIBUTE_UNUSED void *cookie)\n"); | 3937 "\tATTRIBUTE_UNUSED void *cookie)\n"); |
3298 oprintf (d.of, "{\n"); | 3938 oprintf (d.of, "{\n"); |
3299 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n", | 3939 oprintf (d.of, " %s %s * x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n", |
3300 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag, | 3940 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag, |
3301 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); | 3941 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); |
3302 d.indent = 2; | 3942 d.indent = 2; |
3303 walk_type (s, &d); | 3943 d.have_this_obj = true; |
3944 | |
3945 if (s->kind != TYPE_USER_STRUCT) | |
3946 walk_type (s, &d); | |
3947 else | |
3948 { | |
3949 /* User structures have no fields to walk. Simply generate a | |
3950 call to the user-provided PCH walker. */ | |
3951 oprintf (d.of, "%*sif ((void *)(%s) == this_obj)\n", d.indent, "", | |
3952 d.prev_val[3]); | |
3953 oprintf (d.of, "%*s gt_pch_nx (&(%s), op, cookie);\n", | |
3954 d.indent, "", d.val); | |
3955 } | |
3956 | |
3304 oprintf (d.of, "}\n"); | 3957 oprintf (d.of, "}\n"); |
3958 | |
3959 /* Write user-callable entry points for the PCH walking routines. */ | |
3960 if (orig_s->kind == TYPE_USER_STRUCT) | |
3961 write_pch_user_walking_functions (s, &d); | |
3962 | |
3963 for (options_p o = s->u.s.opt; o; o = o->next) | |
3964 if (strcmp (o->name, "for_user") == 0) | |
3965 { | |
3966 write_pch_user_walking_for_structure_body (s, &d); | |
3967 break; | |
3968 } | |
3305 } | 3969 } |
3306 | 3970 |
3307 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */ | 3971 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */ |
3308 | 3972 |
3309 static void | 3973 static void |
3310 write_local (outf_p output_header, type_p structures, type_p param_structs) | 3974 write_local (outf_p output_header, type_p structures) |
3311 { | 3975 { |
3312 type_p s; | 3976 type_p s; |
3313 | 3977 |
3314 if (!output_header) | 3978 if (!output_header) |
3315 return; | 3979 return; |
3980 | |
3316 oprintf (output_header, "\n/* Local pointer-walking routines. */\n"); | 3981 oprintf (output_header, "\n/* Local pointer-walking routines. */\n"); |
3317 for (s = structures; s; s = s->next) | 3982 for (s = structures; s; s = s->next) |
3318 if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO) | 3983 if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO) |
3319 { | 3984 { |
3320 options_p opt; | 3985 options_p opt; |
3351 | 4016 |
3352 if (s->kind == TYPE_LANG_STRUCT) | 4017 if (s->kind == TYPE_LANG_STRUCT) |
3353 { | 4018 { |
3354 type_p ss; | 4019 type_p ss; |
3355 for (ss = s->u.s.lang_struct; ss; ss = ss->next) | 4020 for (ss = s->u.s.lang_struct; ss; ss = ss->next) |
3356 write_local_func_for_structure (s, ss, NULL); | 4021 write_local_func_for_structure (s, ss); |
3357 } | 4022 } |
3358 else | 4023 else |
3359 write_local_func_for_structure (s, s, NULL); | 4024 write_local_func_for_structure (s, s); |
3360 } | 4025 } |
3361 | |
3362 for (s = param_structs; s; s = s->next) | |
3363 if (s->gc_used == GC_POINTED_TO) | |
3364 { | |
3365 type_p *param = s->u.param_struct.param; | |
3366 type_p stru = s->u.param_struct.stru; | |
3367 | |
3368 /* Declare the marker procedure. */ | |
3369 oprintf (output_header, "extern void gt_pch_p_"); | |
3370 output_mangled_typename (output_header, s); | |
3371 oprintf (output_header, | |
3372 "\n (void *, void *, gt_pointer_operator, void *);\n"); | |
3373 | |
3374 if (stru->u.s.line.file == NULL) | |
3375 { | |
3376 fprintf (stderr, "warning: structure `%s' used but not defined\n", | |
3377 s->u.s.tag); | |
3378 continue; | |
3379 } | |
3380 | |
3381 if (stru->kind == TYPE_LANG_STRUCT) | |
3382 { | |
3383 type_p ss; | |
3384 for (ss = stru->u.s.lang_struct; ss; ss = ss->next) | |
3385 write_local_func_for_structure (s, ss, param); | |
3386 } | |
3387 else | |
3388 write_local_func_for_structure (s, stru, param); | |
3389 } | |
3390 } | 4026 } |
3391 | 4027 |
3392 /* Nonzero if S is a type for which typed GC allocators should be output. */ | 4028 /* Nonzero if S is a type for which typed GC allocators should be output. */ |
3393 | 4029 |
3394 #define USED_BY_TYPED_GC_P(s) \ | 4030 #define USED_BY_TYPED_GC_P(s) \ |
3395 (((s->kind == TYPE_POINTER) \ | 4031 ((s->kind == TYPE_POINTER \ |
3396 && ((s->u.p->gc_used == GC_POINTED_TO) \ | 4032 && (s->u.p->gc_used == GC_POINTED_TO \ |
3397 || (s->u.p->gc_used == GC_USED))) \ | 4033 || s->u.p->gc_used == GC_USED)) \ |
3398 || (UNION_OR_STRUCT_P (s) && \ | 4034 || (union_or_struct_p (s) \ |
3399 (((s)->gc_used == GC_POINTED_TO) \ | 4035 && ((s)->gc_used == GC_POINTED_TO \ |
3400 || ((s)->gc_used == GC_MAYBE_POINTED_TO \ | 4036 || ((s)->gc_used == GC_MAYBE_POINTED_TO \ |
3401 && s->u.s.line.file != NULL) \ | 4037 && s->u.s.line.file != NULL) \ |
3402 || ((s)->gc_used == GC_USED \ | 4038 || ((s)->gc_used == GC_USED \ |
3403 && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous")))))) | 4039 && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous"))) \ |
3404 | 4040 || (s->u.s.base_class && opts_have (s->u.s.opt, "tag"))))) |
3405 | 4041 |
3406 /* Write out the 'enum' definition for gt_types_enum. */ | 4042 |
3407 | |
3408 static void | |
3409 write_enum_defn (type_p structures, type_p param_structs) | |
3410 { | |
3411 type_p s; | |
3412 int nbstruct = 0; | |
3413 int nbparamstruct = 0; | |
3414 | |
3415 if (!header_file) | |
3416 return; | |
3417 oprintf (header_file, "\n/* Enumeration of types known. */\n"); | |
3418 oprintf (header_file, "enum gt_types_enum {\n"); | |
3419 for (s = structures; s; s = s->next) | |
3420 if (USED_BY_TYPED_GC_P (s)) | |
3421 { | |
3422 nbstruct++; | |
3423 DBGPRINTF ("write_enum_defn s @ %p nbstruct %d", | |
3424 (void*) s, nbstruct); | |
3425 if (UNION_OR_STRUCT_P (s)) | |
3426 DBGPRINTF ("write_enum_defn s %p #%d is unionorstruct tagged %s", | |
3427 (void*) s, nbstruct, s->u.s.tag); | |
3428 oprintf (header_file, " gt_ggc_e_"); | |
3429 output_mangled_typename (header_file, s); | |
3430 oprintf (header_file, ",\n"); | |
3431 } | |
3432 for (s = param_structs; s; s = s->next) | |
3433 if (s->gc_used == GC_POINTED_TO) | |
3434 { | |
3435 nbparamstruct++; | |
3436 DBGPRINTF ("write_enum_defn s %p nbparamstruct %d", | |
3437 (void*) s, nbparamstruct); | |
3438 oprintf (header_file, " gt_e_"); | |
3439 output_mangled_typename (header_file, s); | |
3440 oprintf (header_file, ",\n"); | |
3441 } | |
3442 oprintf (header_file, " gt_types_enum_last\n"); | |
3443 oprintf (header_file, "};\n"); | |
3444 if (verbosity_level >= 2) | |
3445 printf ("%s handled %d GTY-ed structures & %d parameterized structures.\n", | |
3446 progname, nbstruct, nbparamstruct); | |
3447 | |
3448 } | |
3449 | 4043 |
3450 /* Might T contain any non-pointer elements? */ | 4044 /* Might T contain any non-pointer elements? */ |
3451 | 4045 |
3452 static int | 4046 static int |
3453 contains_scalar_p (type_p t) | 4047 contains_scalar_p (type_p t) |
3457 case TYPE_STRING: | 4051 case TYPE_STRING: |
3458 case TYPE_POINTER: | 4052 case TYPE_POINTER: |
3459 return 0; | 4053 return 0; |
3460 case TYPE_ARRAY: | 4054 case TYPE_ARRAY: |
3461 return contains_scalar_p (t->u.a.p); | 4055 return contains_scalar_p (t->u.a.p); |
4056 case TYPE_USER_STRUCT: | |
4057 /* User-marked structures will typically contain pointers. */ | |
4058 return 0; | |
3462 default: | 4059 default: |
3463 /* Could also check for structures that have no non-pointer | 4060 /* Could also check for structures that have no non-pointer |
3464 fields, but there aren't enough of those to worry about. */ | 4061 fields, but there aren't enough of those to worry about. */ |
3465 return 1; | 4062 return 1; |
3466 } | 4063 } |
3550 oprintf (base_files[fnum], "};\n"); | 4147 oprintf (base_files[fnum], "};\n"); |
3551 } | 4148 } |
3552 } | 4149 } |
3553 } | 4150 } |
3554 | 4151 |
4152 /* Finish off the created gt_clear_caches_file_c functions. */ | |
4153 | |
4154 static void | |
4155 finish_cache_funcs (flist *flp) | |
4156 { | |
4157 struct flist *fli2; | |
4158 | |
4159 for (fli2 = flp; fli2; fli2 = fli2->next) | |
4160 if (fli2->started_p) | |
4161 { | |
4162 oprintf (fli2->f, "}\n\n"); | |
4163 } | |
4164 | |
4165 for (fli2 = flp; fli2 && base_files; fli2 = fli2->next) | |
4166 if (fli2->started_p) | |
4167 { | |
4168 lang_bitmap bitmap = get_lang_bitmap (fli2->file); | |
4169 int fnum; | |
4170 | |
4171 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1) | |
4172 if (bitmap & 1) | |
4173 { | |
4174 oprintf (base_files[fnum], "extern void gt_clear_caches_"); | |
4175 put_mangled_filename (base_files[fnum], fli2->file); | |
4176 oprintf (base_files[fnum], " ();\n"); | |
4177 } | |
4178 } | |
4179 | |
4180 for (size_t fnum = 0; base_files && fnum < num_lang_dirs; fnum++) | |
4181 oprintf (base_files[fnum], "void\ngt_clear_caches ()\n{\n"); | |
4182 | |
4183 for (fli2 = flp; fli2; fli2 = fli2->next) | |
4184 if (fli2->started_p) | |
4185 { | |
4186 lang_bitmap bitmap = get_lang_bitmap (fli2->file); | |
4187 int fnum; | |
4188 | |
4189 fli2->started_p = 0; | |
4190 | |
4191 for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1) | |
4192 if (bitmap & 1) | |
4193 { | |
4194 oprintf (base_files[fnum], " gt_clear_caches_"); | |
4195 put_mangled_filename (base_files[fnum], fli2->file); | |
4196 oprintf (base_files[fnum], " ();\n"); | |
4197 } | |
4198 } | |
4199 | |
4200 for (size_t fnum = 0; base_files && fnum < num_lang_dirs; fnum++) | |
4201 { | |
4202 oprintf (base_files[fnum], "}\n"); | |
4203 } | |
4204 } | |
4205 | |
3555 /* Write the first three fields (pointer, count and stride) for | 4206 /* Write the first three fields (pointer, count and stride) for |
3556 root NAME to F. V and LINE are as for write_root. | 4207 root NAME to F. V and LINE are as for write_root. |
3557 | 4208 |
3558 Return true if the entry could be written; return false on error. */ | 4209 Return true if the entry could be written; return false on error. */ |
3559 | 4210 |
3589 which has type FIELD_TYPE. Parameters F to EMIT_PCH are the parameters | 4240 which has type FIELD_TYPE. Parameters F to EMIT_PCH are the parameters |
3590 of the caller. */ | 4241 of the caller. */ |
3591 | 4242 |
3592 static void | 4243 static void |
3593 write_field_root (outf_p f, pair_p v, type_p type, const char *name, | 4244 write_field_root (outf_p f, pair_p v, type_p type, const char *name, |
3594 int has_length, struct fileloc *line, const char *if_marked, | 4245 int has_length, struct fileloc *line, |
3595 bool emit_pch, type_p field_type, const char *field_name) | 4246 bool emit_pch, type_p field_type, const char *field_name) |
3596 { | 4247 { |
4248 struct pair newv; | |
3597 /* If the field reference is relative to V, rather than to some | 4249 /* If the field reference is relative to V, rather than to some |
3598 subcomponent of V, we can mark any subarrays with a single stride. | 4250 subcomponent of V, we can mark any subarrays with a single stride. |
3599 We're effectively treating the field as a global variable in its | 4251 We're effectively treating the field as a global variable in its |
3600 own right. */ | 4252 own right. */ |
3601 if (v && type == v->type) | 4253 if (v && type == v->type) |
3602 { | 4254 { |
3603 struct pair newv; | |
3604 | |
3605 newv = *v; | 4255 newv = *v; |
3606 newv.type = field_type; | 4256 newv.type = field_type; |
3607 newv.name = ACONCAT ((v->name, ".", field_name, NULL)); | 4257 newv.name = ACONCAT ((v->name, ".", field_name, NULL)); |
3608 v = &newv; | 4258 v = &newv; |
3609 } | 4259 } |
3610 /* Otherwise, any arrays nested in the structure are too complex to | 4260 /* Otherwise, any arrays nested in the structure are too complex to |
3611 handle. */ | 4261 handle. */ |
3612 else if (field_type->kind == TYPE_ARRAY) | 4262 else if (field_type->kind == TYPE_ARRAY) |
3613 v = NULL; | 4263 v = NULL; |
3614 write_root (f, v, field_type, ACONCAT ((name, ".", field_name, NULL)), | 4264 write_root (f, v, field_type, ACONCAT ((name, ".", field_name, NULL)), |
3615 has_length, line, if_marked, emit_pch); | 4265 has_length, line, emit_pch); |
3616 } | 4266 } |
3617 | 4267 |
3618 /* Write out to F the table entry and any marker routines needed to | 4268 /* Write out to F the table entry and any marker routines needed to |
3619 mark NAME as TYPE. V can be one of three values: | 4269 mark NAME as TYPE. V can be one of three values: |
3620 | 4270 |
3625 - the outermost array that contains NAME, if NAME is part of an array. | 4275 - the outermost array that contains NAME, if NAME is part of an array. |
3626 | 4276 |
3627 - the C variable that contains NAME, if NAME is not part of an array. | 4277 - the C variable that contains NAME, if NAME is not part of an array. |
3628 | 4278 |
3629 LINE is the line of the C source that declares the root variable. | 4279 LINE is the line of the C source that declares the root variable. |
3630 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED | 4280 HAS_LENGTH is nonzero iff V was a variable-length array. */ |
3631 is nonzero iff we are building the root table for hash table caches. */ | |
3632 | 4281 |
3633 static void | 4282 static void |
3634 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length, | 4283 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length, |
3635 struct fileloc *line, const char *if_marked, bool emit_pch) | 4284 struct fileloc *line, bool emit_pch) |
3636 { | 4285 { |
3637 switch (type->kind) | 4286 switch (type->kind) |
3638 { | 4287 { |
3639 case TYPE_STRUCT: | 4288 case TYPE_STRUCT: |
3640 { | 4289 { |
3649 if (strcmp (o->name, "skip") == 0) | 4298 if (strcmp (o->name, "skip") == 0) |
3650 skip_p = 1; | 4299 skip_p = 1; |
3651 else if (strcmp (o->name, "desc") == 0 | 4300 else if (strcmp (o->name, "desc") == 0 |
3652 && o->kind == OPTION_STRING) | 4301 && o->kind == OPTION_STRING) |
3653 desc = o->info.string; | 4302 desc = o->info.string; |
3654 else if (strcmp (o->name, "param_is") == 0) | |
3655 ; | |
3656 else | 4303 else |
3657 error_at_line (line, | 4304 error_at_line (line, |
3658 "field `%s' of global `%s' has unknown option `%s'", | 4305 "field `%s' of global `%s' has unknown option `%s'", |
3659 fld->name, name, o->name); | 4306 fld->name, name, o->name); |
3660 | 4307 |
3681 name, fld->name, validf->name, | 4328 name, fld->name, validf->name, |
3682 name, fld->name, ufld->name, tag); | 4329 name, fld->name, ufld->name, tag); |
3683 validf = ufld; | 4330 validf = ufld; |
3684 } | 4331 } |
3685 if (validf != NULL) | 4332 if (validf != NULL) |
3686 write_field_root (f, v, type, name, 0, line, if_marked, | 4333 write_field_root (f, v, type, name, 0, line, emit_pch, |
3687 emit_pch, validf->type, | 4334 validf->type, |
3688 ACONCAT ((fld->name, ".", | 4335 ACONCAT ((fld->name, ".", |
3689 validf->name, NULL))); | 4336 validf->name, NULL))); |
3690 } | 4337 } |
3691 else if (desc) | 4338 else if (desc) |
3692 error_at_line (line, | 4339 error_at_line (line, |
3693 "global `%s.%s' has `desc' option but is not union", | 4340 "global `%s.%s' has `desc' option but is not union", |
3694 name, fld->name); | 4341 name, fld->name); |
3695 else | 4342 else |
3696 write_field_root (f, v, type, name, 0, line, if_marked, | 4343 write_field_root (f, v, type, name, 0, line, emit_pch, fld->type, |
3697 emit_pch, fld->type, fld->name); | 4344 fld->name); |
3698 } | 4345 } |
3699 } | 4346 } |
3700 break; | 4347 break; |
3701 | 4348 |
3702 case TYPE_ARRAY: | 4349 case TYPE_ARRAY: |
3703 { | 4350 { |
3704 char *newname; | 4351 char *newname; |
3705 newname = xasprintf ("%s[0]", name); | 4352 newname = xasprintf ("%s[0]", name); |
3706 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked, | 4353 write_root (f, v, type->u.a.p, newname, has_length, line, emit_pch); |
3707 emit_pch); | |
3708 free (newname); | 4354 free (newname); |
3709 } | 4355 } |
3710 break; | 4356 break; |
3711 | 4357 |
4358 case TYPE_USER_STRUCT: | |
4359 error_at_line (line, "`%s' must be a pointer type, because it is " | |
4360 "a GC root and its type is marked with GTY((user))", | |
4361 v->name); | |
4362 break; | |
4363 | |
3712 case TYPE_POINTER: | 4364 case TYPE_POINTER: |
3713 { | 4365 { |
3714 type_p tp; | 4366 const_type_p tp; |
3715 | 4367 |
3716 if (!start_root_entry (f, v, name, line)) | 4368 if (!start_root_entry (f, v, name, line)) |
3717 return; | 4369 return; |
3718 | 4370 |
3719 tp = type->u.p; | 4371 tp = type->u.p; |
3720 | 4372 |
3721 if (!has_length && UNION_OR_STRUCT_P (tp)) | 4373 if (!has_length && union_or_struct_p (tp)) |
3722 { | 4374 { |
3723 oprintf (f, " >_ggc_mx_%s,\n", tp->u.s.tag); | 4375 tp = get_ultimate_base_class (tp); |
4376 const char *id_for_tag = filter_type_name (tp->u.s.tag); | |
4377 oprintf (f, " >_ggc_mx_%s,\n", id_for_tag); | |
3724 if (emit_pch) | 4378 if (emit_pch) |
3725 oprintf (f, " >_pch_nx_%s", tp->u.s.tag); | 4379 oprintf (f, " >_pch_nx_%s", id_for_tag); |
3726 else | 4380 else |
3727 oprintf (f, " NULL"); | 4381 oprintf (f, " NULL"); |
3728 } | 4382 if (id_for_tag != tp->u.s.tag) |
3729 else if (!has_length && tp->kind == TYPE_PARAM_STRUCT) | 4383 free (CONST_CAST (char *, id_for_tag)); |
3730 { | |
3731 oprintf (f, " >_ggc_m_"); | |
3732 output_mangled_typename (f, tp); | |
3733 if (emit_pch) | |
3734 { | |
3735 oprintf (f, ",\n >_pch_n_"); | |
3736 output_mangled_typename (f, tp); | |
3737 } | |
3738 else | |
3739 oprintf (f, ",\n NULL"); | |
3740 } | 4384 } |
3741 else if (has_length | 4385 else if (has_length |
3742 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp))) | 4386 && (tp->kind == TYPE_POINTER || union_or_struct_p (tp))) |
3743 { | 4387 { |
3744 oprintf (f, " >_ggc_ma_%s,\n", name); | 4388 oprintf (f, " >_ggc_ma_%s,\n", name); |
3745 if (emit_pch) | 4389 if (emit_pch) |
3746 oprintf (f, " >_pch_na_%s", name); | 4390 oprintf (f, " >_pch_na_%s", name); |
3747 else | 4391 else |
3751 { | 4395 { |
3752 error_at_line (line, | 4396 error_at_line (line, |
3753 "global `%s' is pointer to unimplemented type", | 4397 "global `%s' is pointer to unimplemented type", |
3754 name); | 4398 name); |
3755 } | 4399 } |
3756 if (if_marked) | |
3757 oprintf (f, ",\n &%s", if_marked); | |
3758 oprintf (f, "\n },\n"); | 4400 oprintf (f, "\n },\n"); |
3759 } | 4401 } |
3760 break; | 4402 break; |
3761 | 4403 |
3762 case TYPE_STRING: | 4404 case TYPE_STRING: |
3771 break; | 4413 break; |
3772 | 4414 |
3773 case TYPE_SCALAR: | 4415 case TYPE_SCALAR: |
3774 break; | 4416 break; |
3775 | 4417 |
3776 default: | 4418 case TYPE_NONE: |
4419 case TYPE_UNDEFINED: | |
4420 case TYPE_UNION: | |
4421 case TYPE_LANG_STRUCT: | |
3777 error_at_line (line, "global `%s' is unimplemented type", name); | 4422 error_at_line (line, "global `%s' is unimplemented type", name); |
3778 } | 4423 } |
3779 } | 4424 } |
3780 | 4425 |
3781 /* This generates a routine to walk an array. */ | 4426 /* This generates a routine to walk an array. */ |
3791 d.cookie = wtd; | 4436 d.cookie = wtd; |
3792 d.indent = 2; | 4437 d.indent = 2; |
3793 d.line = &v->line; | 4438 d.line = &v->line; |
3794 d.opt = v->opt; | 4439 d.opt = v->opt; |
3795 d.bitmap = get_lang_bitmap (v->line.file); | 4440 d.bitmap = get_lang_bitmap (v->line.file); |
3796 d.param = NULL; | |
3797 | 4441 |
3798 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name); | 4442 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name); |
3799 | 4443 |
3800 if (wtd->param_prefix) | 4444 if (wtd->param_prefix) |
3801 { | 4445 { |
3808 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n" | 4452 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n" |
3809 " ATTRIBUTE_UNUSED void * cookie)\n"); | 4453 " ATTRIBUTE_UNUSED void * cookie)\n"); |
3810 oprintf (d.of, "{\n"); | 4454 oprintf (d.of, "{\n"); |
3811 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name; | 4455 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name; |
3812 d.process_field = write_types_local_process_field; | 4456 d.process_field = write_types_local_process_field; |
4457 d.have_this_obj = true; | |
3813 walk_type (v->type, &d); | 4458 walk_type (v->type, &d); |
3814 oprintf (f, "}\n\n"); | 4459 oprintf (f, "}\n\n"); |
3815 } | 4460 } |
3816 | 4461 |
3817 d.opt = v->opt; | 4462 d.opt = v->opt; |
3819 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n", | 4464 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n", |
3820 wtd->prefix, v->name); | 4465 wtd->prefix, v->name); |
3821 oprintf (f, "{\n"); | 4466 oprintf (f, "{\n"); |
3822 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name; | 4467 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name; |
3823 d.process_field = write_types_process_field; | 4468 d.process_field = write_types_process_field; |
4469 d.have_this_obj = false; | |
3824 walk_type (v->type, &d); | 4470 walk_type (v->type, &d); |
3825 free (prevval3); | 4471 free (prevval3); |
3826 oprintf (f, "}\n\n"); | 4472 oprintf (f, "}\n\n"); |
3827 } | 4473 } |
3828 | 4474 |
3847 if (strcmp (o->name, "length") == 0 | 4493 if (strcmp (o->name, "length") == 0 |
3848 && o->kind == OPTION_STRING) | 4494 && o->kind == OPTION_STRING) |
3849 length = o->info.string; | 4495 length = o->info.string; |
3850 else if (strcmp (o->name, "deletable") == 0) | 4496 else if (strcmp (o->name, "deletable") == 0) |
3851 deletable_p = 1; | 4497 deletable_p = 1; |
3852 else if (strcmp (o->name, "param_is") == 0) | 4498 else if (strcmp (o->name, "cache") == 0) |
3853 ; | |
3854 else if (strncmp (o->name, "param", 5) == 0 | |
3855 && ISDIGIT (o->name[5]) && strcmp (o->name + 6, "_is") == 0) | |
3856 ; | |
3857 else if (strcmp (o->name, "if_marked") == 0) | |
3858 ; | 4499 ; |
3859 else | 4500 else |
3860 error_at_line (&v->line, | 4501 error_at_line (&v->line, |
3861 "global `%s' has unknown option `%s'", | 4502 "global `%s' has unknown option `%s'", |
3862 v->name, o->name); | 4503 v->name, o->name); |
3898 options_p o; | 4539 options_p o; |
3899 | 4540 |
3900 for (o = v->opt; o; o = o->next) | 4541 for (o = v->opt; o; o = o->next) |
3901 if (strcmp (o->name, "length") == 0) | 4542 if (strcmp (o->name, "length") == 0) |
3902 length_p = 1; | 4543 length_p = 1; |
3903 else if (strcmp (o->name, "deletable") == 0 | 4544 else if (strcmp (o->name, "deletable") == 0) |
3904 || strcmp (o->name, "if_marked") == 0) | |
3905 skip_p = 1; | 4545 skip_p = 1; |
3906 | 4546 |
3907 if (skip_p) | 4547 if (skip_p) |
3908 continue; | 4548 continue; |
3909 | 4549 |
3917 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_"); | 4557 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_"); |
3918 put_mangled_filename (f, v->line.file); | 4558 put_mangled_filename (f, v->line.file); |
3919 oprintf (f, "[] = {\n"); | 4559 oprintf (f, "[] = {\n"); |
3920 } | 4560 } |
3921 | 4561 |
3922 write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch); | 4562 write_root (f, v, v->type, v->name, length_p, &v->line, emit_pch); |
3923 } | 4563 } |
3924 | 4564 |
3925 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab", | 4565 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab", |
3926 "gt_ggc_rtab"); | 4566 "gt_ggc_rtab"); |
3927 | 4567 |
3934 options_p o; | 4574 options_p o; |
3935 | 4575 |
3936 for (o = v->opt; o; o = o->next) | 4576 for (o = v->opt; o; o = o->next) |
3937 if (strcmp (o->name, "deletable") == 0) | 4577 if (strcmp (o->name, "deletable") == 0) |
3938 skip_p = 0; | 4578 skip_p = 0; |
3939 else if (strcmp (o->name, "if_marked") == 0) | |
3940 skip_p = 1; | |
3941 | 4579 |
3942 if (skip_p) | 4580 if (skip_p) |
3943 continue; | 4581 continue; |
3944 | 4582 |
3945 for (fli = flp; fli; fli = fli->next) | 4583 for (fli = flp; fli; fli = fli->next) |
3964 for (v = variables; v; v = v->next) | 4602 for (v = variables; v; v = v->next) |
3965 { | 4603 { |
3966 outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*, | 4604 outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*, |
3967 v->line.file)); | 4605 v->line.file)); |
3968 struct flist *fli; | 4606 struct flist *fli; |
3969 const char *if_marked = NULL; | 4607 bool cache = false; |
3970 int length_p = 0; | |
3971 options_p o; | 4608 options_p o; |
3972 | 4609 |
3973 for (o = v->opt; o; o = o->next) | 4610 for (o = v->opt; o; o = o->next) |
3974 if (strcmp (o->name, "length") == 0) | 4611 if (strcmp (o->name, "cache") == 0) |
3975 length_p = 1; | 4612 cache = true; |
3976 else if (strcmp (o->name, "if_marked") == 0 | 4613 if (!cache) |
3977 && o->kind == OPTION_STRING) | |
3978 if_marked = o->info.string; | |
3979 if (if_marked == NULL) | |
3980 continue; | 4614 continue; |
3981 if (v->type->kind != TYPE_POINTER | |
3982 || v->type->u.p->kind != TYPE_PARAM_STRUCT | |
3983 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0)) | |
3984 { | |
3985 error_at_line (&v->line, | |
3986 "if_marked option used but not hash table"); | |
3987 continue; | |
3988 } | |
3989 | 4615 |
3990 for (fli = flp; fli; fli = fli->next) | 4616 for (fli = flp; fli; fli = fli->next) |
3991 if (fli->f == f) | 4617 if (fli->f == f) |
3992 break; | 4618 break; |
3993 if (!fli->started_p) | 4619 if (!fli->started_p) |
3994 { | 4620 { |
3995 fli->started_p = 1; | 4621 fli->started_p = 1; |
3996 | 4622 |
3997 oprintf (f, "EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc_"); | 4623 oprintf (f, "void\ngt_clear_caches_"); |
3998 put_mangled_filename (f, v->line.file); | 4624 put_mangled_filename (f, v->line.file); |
3999 oprintf (f, "[] = {\n"); | 4625 oprintf (f, " ()\n{\n"); |
4000 } | 4626 } |
4001 | 4627 |
4002 write_root (f, v, v->type->u.p->u.param_struct.param[0], | 4628 oprintf (f, " gt_cleare_cache (%s);\n", v->name); |
4003 v->name, length_p, &v->line, if_marked, emit_pch); | 4629 } |
4004 } | 4630 |
4005 | 4631 finish_cache_funcs (flp); |
4006 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab", | |
4007 "gt_ggc_cache_rtab"); | |
4008 | 4632 |
4009 if (!emit_pch) | 4633 if (!emit_pch) |
4010 return; | 4634 return; |
4011 | 4635 |
4012 for (v = variables; v; v = v->next) | 4636 for (v = variables; v; v = v->next) |
4013 { | 4637 { |
4014 outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*, | 4638 outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*, |
4015 v->line.file)); | 4639 v->line.file)); |
4016 struct flist *fli; | 4640 struct flist *fli; |
4017 int length_p = 0; | 4641 int skip_p = 0; |
4018 int if_marked_p = 0; | |
4019 options_p o; | 4642 options_p o; |
4020 | 4643 |
4021 for (o = v->opt; o; o = o->next) | 4644 for (o = v->opt; o; o = o->next) |
4022 if (strcmp (o->name, "length") == 0) | 4645 if (strcmp (o->name, "deletable") == 0) |
4023 length_p = 1; | 4646 { |
4024 else if (strcmp (o->name, "if_marked") == 0) | 4647 skip_p = 1; |
4025 if_marked_p = 1; | 4648 break; |
4026 | 4649 } |
4027 if (!if_marked_p) | 4650 |
4651 if (skip_p) | |
4652 continue; | |
4653 | |
4654 if (!contains_scalar_p (v->type)) | |
4028 continue; | 4655 continue; |
4029 | 4656 |
4030 for (fli = flp; fli; fli = fli->next) | 4657 for (fli = flp; fli; fli = fli->next) |
4031 if (fli->f == f) | 4658 if (fli->f == f) |
4032 break; | 4659 break; |
4033 if (!fli->started_p) | 4660 if (!fli->started_p) |
4034 { | 4661 { |
4035 fli->started_p = 1; | 4662 fli->started_p = 1; |
4036 | 4663 |
4037 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rc_"); | |
4038 put_mangled_filename (f, v->line.file); | |
4039 oprintf (f, "[] = {\n"); | |
4040 } | |
4041 | |
4042 write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch); | |
4043 } | |
4044 | |
4045 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab", | |
4046 "gt_pch_cache_rtab"); | |
4047 | |
4048 for (v = variables; v; v = v->next) | |
4049 { | |
4050 outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*, | |
4051 v->line.file)); | |
4052 struct flist *fli; | |
4053 int skip_p = 0; | |
4054 options_p o; | |
4055 | |
4056 for (o = v->opt; o; o = o->next) | |
4057 if (strcmp (o->name, "deletable") == 0 | |
4058 || strcmp (o->name, "if_marked") == 0) | |
4059 skip_p = 1; | |
4060 | |
4061 if (skip_p) | |
4062 continue; | |
4063 | |
4064 if (!contains_scalar_p (v->type)) | |
4065 continue; | |
4066 | |
4067 for (fli = flp; fli; fli = fli->next) | |
4068 if (fli->f == f) | |
4069 break; | |
4070 if (!fli->started_p) | |
4071 { | |
4072 fli->started_p = 1; | |
4073 | |
4074 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_"); | 4664 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_"); |
4075 put_mangled_filename (f, v->line.file); | 4665 put_mangled_filename (f, v->line.file); |
4076 oprintf (f, "[] = {\n"); | 4666 oprintf (f, "[] = {\n"); |
4077 } | 4667 } |
4078 | 4668 |
4082 | 4672 |
4083 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab", | 4673 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab", |
4084 "gt_pch_scalar_rtab"); | 4674 "gt_pch_scalar_rtab"); |
4085 } | 4675 } |
4086 | 4676 |
4087 /* Record the definition of a generic VEC structure, as if we had expanded | |
4088 the macros in vec.h: | |
4089 | |
4090 typedef struct VEC_<type>_base GTY(()) { | |
4091 unsigned num; | |
4092 unsigned alloc; | |
4093 <type> GTY((length ("%h.num"))) vec[1]; | |
4094 } VEC_<type>_base | |
4095 | |
4096 where the GTY(()) tags are only present if is_scalar is _false_. */ | |
4097 | |
4098 void | |
4099 note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos) | |
4100 { | |
4101 pair_p fields; | |
4102 type_p t; | |
4103 options_p o; | |
4104 type_p len_ty = create_scalar_type ("unsigned"); | |
4105 const char *name = concat ("VEC_", type_name, "_base", (char *) 0); | |
4106 | |
4107 if (is_scalar) | |
4108 { | |
4109 t = create_scalar_type (type_name); | |
4110 o = 0; | |
4111 } | |
4112 else | |
4113 { | |
4114 t = resolve_typedef (type_name, pos); | |
4115 o = create_string_option (0, "length", "%h.num"); | |
4116 } | |
4117 /* We assemble the field list in reverse order. */ | |
4118 fields = create_field_at (0, create_array (t, "1"), "vec", o, pos); | |
4119 fields = create_field_at (fields, len_ty, "alloc", 0, pos); | |
4120 fields = create_field_at (fields, len_ty, "num", 0, pos); | |
4121 | |
4122 do_typedef (name, new_structure (name, 0, pos, fields, 0), pos); | |
4123 } | |
4124 | |
4125 /* Record the definition of an allocation-specific VEC structure, as if | |
4126 we had expanded the macros in vec.h: | |
4127 | |
4128 typedef struct VEC_<type>_<astrat> { | |
4129 VEC_<type>_base base; | |
4130 } VEC_<type>_<astrat>; | |
4131 */ | |
4132 void | |
4133 note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos) | |
4134 { | |
4135 const char *astratname = concat ("VEC_", type, "_", astrat, (char *) 0); | |
4136 const char *basename = concat ("VEC_", type, "_base", (char *) 0); | |
4137 | |
4138 pair_p field = create_field_at (0, resolve_typedef (basename, pos), | |
4139 "base", 0, pos); | |
4140 | |
4141 do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos); | |
4142 } | |
4143 | |
4144 /* Returns the specifier keyword for a string or union type S, empty string | |
4145 otherwise. */ | |
4146 | |
4147 static const char * | |
4148 get_type_specifier (const type_p s) | |
4149 { | |
4150 if (s->kind == TYPE_STRUCT || s->kind == TYPE_LANG_STRUCT) | |
4151 return "struct "; | |
4152 if (s->kind == TYPE_UNION) | |
4153 return "union "; | |
4154 return ""; | |
4155 } | |
4156 | |
4157 /* TRUE if type S has the GTY variable_size annotation. */ | |
4158 | |
4159 static bool | |
4160 variable_size_p (const type_p s) | |
4161 { | |
4162 options_p o; | |
4163 for (o = s->u.s.opt; o; o = o->next) | |
4164 if (strcmp (o->name, "variable_size") == 0) | |
4165 return true; | |
4166 return false; | |
4167 } | |
4168 | |
4169 enum alloc_quantity | |
4170 { single, vector }; | |
4171 enum alloc_zone | |
4172 { any_zone, specific_zone }; | |
4173 | |
4174 /* Writes one typed allocator definition for type identifier TYPE_NAME with | |
4175 optional type specifier TYPE_SPECIFIER. The allocator name will contain | |
4176 ALLOCATOR_TYPE. If VARIABLE_SIZE is true, the allocator will have an extra | |
4177 parameter specifying number of bytes to allocate. If QUANTITY is set to | |
4178 VECTOR, a vector allocator will be output, if ZONE is set to SPECIFIC_ZONE, | |
4179 the allocator will be zone-specific. */ | |
4180 | |
4181 static void | |
4182 write_typed_alloc_def (bool variable_size, const char *type_specifier, | |
4183 const char *type_name, const char *allocator_type, | |
4184 enum alloc_quantity quantity, enum alloc_zone zone) | |
4185 { | |
4186 bool two_args = variable_size && (quantity == vector); | |
4187 bool third_arg = ((zone == specific_zone) | |
4188 && (variable_size || (quantity == vector))); | |
4189 | |
4190 oprintf (header_file, "#define ggc_alloc_%s%s", allocator_type, type_name); | |
4191 oprintf (header_file, "(%s%s%s%s%s) ", | |
4192 (variable_size ? "SIZE" : ""), | |
4193 (two_args ? ", " : ""), | |
4194 (quantity == vector) ? "n" : "", | |
4195 (third_arg ? ", " : ""), (zone == specific_zone) ? "z" : ""); | |
4196 oprintf (header_file, "((%s%s *)", type_specifier, type_name); | |
4197 oprintf (header_file, "(ggc_internal_%salloc_stat (", allocator_type); | |
4198 if (zone == specific_zone) | |
4199 oprintf (header_file, "z, "); | |
4200 if (variable_size) | |
4201 oprintf (header_file, "SIZE"); | |
4202 else | |
4203 oprintf (header_file, "sizeof (%s%s)", type_specifier, type_name); | |
4204 if (quantity == vector) | |
4205 oprintf (header_file, ", n"); | |
4206 oprintf (header_file, " MEM_STAT_INFO)))\n"); | |
4207 } | |
4208 | |
4209 /* Writes a typed allocator definition for a struct or union S. */ | |
4210 | |
4211 static void | |
4212 write_typed_struct_alloc_def (const type_p s, const char *allocator_type, | |
4213 enum alloc_quantity quantity, | |
4214 enum alloc_zone zone) | |
4215 { | |
4216 write_typed_alloc_def (variable_size_p (s), get_type_specifier (s), | |
4217 s->u.s.tag, allocator_type, quantity, zone); | |
4218 } | |
4219 | |
4220 /* Writes a typed allocator definition for a typedef P. */ | |
4221 | |
4222 static void | |
4223 write_typed_typedef_alloc_def (const pair_p p, const char *allocator_type, | |
4224 enum alloc_quantity quantity, | |
4225 enum alloc_zone zone) | |
4226 { | |
4227 write_typed_alloc_def (variable_size_p (p->type), "", p->name, | |
4228 allocator_type, quantity, zone); | |
4229 } | |
4230 | |
4231 /* Writes typed allocator definitions for the types in STRUCTURES and | |
4232 TYPEDEFS that are used by GC. */ | |
4233 | |
4234 static void | |
4235 write_typed_alloc_defns (const type_p structures, const pair_p typedefs) | |
4236 { | |
4237 type_p s; | |
4238 pair_p p; | |
4239 | |
4240 oprintf (header_file, | |
4241 "\n/* Allocators for known structs and unions. */\n\n"); | |
4242 for (s = structures; s; s = s->next) | |
4243 { | |
4244 if (!USED_BY_TYPED_GC_P (s)) | |
4245 continue; | |
4246 write_typed_struct_alloc_def (s, "", single, any_zone); | |
4247 write_typed_struct_alloc_def (s, "cleared_", single, any_zone); | |
4248 write_typed_struct_alloc_def (s, "vec_", vector, any_zone); | |
4249 write_typed_struct_alloc_def (s, "cleared_vec_", vector, any_zone); | |
4250 write_typed_struct_alloc_def (s, "zone_", single, specific_zone); | |
4251 write_typed_struct_alloc_def (s, "zone_cleared_", single, | |
4252 specific_zone); | |
4253 write_typed_struct_alloc_def (s, "zone_vec_", vector, specific_zone); | |
4254 write_typed_struct_alloc_def (s, "zone_cleared_vec_", vector, | |
4255 specific_zone); | |
4256 } | |
4257 | |
4258 oprintf (header_file, "\n/* Allocators for known typedefs. */\n"); | |
4259 for (p = typedefs; p; p = p->next) | |
4260 { | |
4261 s = p->type; | |
4262 if (!USED_BY_TYPED_GC_P (s) || (strcmp (p->name, s->u.s.tag) == 0)) | |
4263 continue; | |
4264 write_typed_typedef_alloc_def (p, "", single, any_zone); | |
4265 write_typed_typedef_alloc_def (p, "cleared_", single, any_zone); | |
4266 write_typed_typedef_alloc_def (p, "vec_", vector, any_zone); | |
4267 write_typed_typedef_alloc_def (p, "cleared_vec_", vector, any_zone); | |
4268 write_typed_typedef_alloc_def (p, "zone_", single, specific_zone); | |
4269 write_typed_typedef_alloc_def (p, "zone_cleared_", single, | |
4270 specific_zone); | |
4271 write_typed_typedef_alloc_def (p, "zone_cleared_vec_", vector, | |
4272 specific_zone); | |
4273 } | |
4274 } | |
4275 | |
4276 /* Prints not-as-ugly version of a typename of T to OF. Trades the uniquness | 4677 /* Prints not-as-ugly version of a typename of T to OF. Trades the uniquness |
4277 guaranteee for somewhat increased readability. If name conflicts do happen, | 4678 guaranteee for somewhat increased readability. If name conflicts do happen, |
4278 this funcion will have to be adjusted to be more like | 4679 this funcion will have to be adjusted to be more like |
4279 output_mangled_typename. */ | 4680 output_mangled_typename. */ |
4280 | |
4281 static void | |
4282 output_typename (outf_p of, const_type_p t) | |
4283 { | |
4284 switch (t->kind) | |
4285 { | |
4286 case TYPE_STRING: | |
4287 oprintf (of, "str"); | |
4288 break; | |
4289 case TYPE_SCALAR: | |
4290 oprintf (of, "scalar"); | |
4291 break; | |
4292 case TYPE_POINTER: | |
4293 output_typename (of, t->u.p); | |
4294 break; | |
4295 case TYPE_STRUCT: | |
4296 case TYPE_UNION: | |
4297 case TYPE_LANG_STRUCT: | |
4298 oprintf (of, "%s", t->u.s.tag); | |
4299 break; | |
4300 case TYPE_PARAM_STRUCT: | |
4301 { | |
4302 int i; | |
4303 for (i = 0; i < NUM_PARAM; i++) | |
4304 if (t->u.param_struct.param[i] != NULL) | |
4305 { | |
4306 output_typename (of, t->u.param_struct.param[i]); | |
4307 oprintf (of, "_"); | |
4308 } | |
4309 output_typename (of, t->u.param_struct.stru); | |
4310 break; | |
4311 } | |
4312 default: | |
4313 gcc_unreachable (); | |
4314 } | |
4315 } | |
4316 | |
4317 /* Writes a typed GC allocator for type S that is suitable as a callback for | |
4318 the splay tree implementation in libiberty. */ | |
4319 | |
4320 static void | |
4321 write_splay_tree_allocator_def (const_type_p s) | |
4322 { | |
4323 outf_p of = get_output_file_with_visibility (NULL); | |
4324 oprintf (of, "void * ggc_alloc_splay_tree_"); | |
4325 output_typename (of, s); | |
4326 oprintf (of, " (int sz, void * nl)\n"); | |
4327 oprintf (of, "{\n"); | |
4328 oprintf (of, " return ggc_splay_alloc ("); | |
4329 oprintf (of, "gt_e_"); | |
4330 output_mangled_typename (of, s); | |
4331 oprintf (of, ", sz, nl);\n"); | |
4332 oprintf (of, "}\n\n"); | |
4333 } | |
4334 | |
4335 /* Writes typed GC allocators for PARAM_STRUCTS that are suitable as callbacks | |
4336 for the splay tree implementation in libiberty. */ | |
4337 | |
4338 static void | |
4339 write_splay_tree_allocators (const_type_p param_structs) | |
4340 { | |
4341 const_type_p s; | |
4342 | |
4343 oprintf (header_file, "\n/* Splay tree callback allocators. */\n"); | |
4344 for (s = param_structs; s; s = s->next) | |
4345 if (s->gc_used == GC_POINTED_TO) | |
4346 { | |
4347 oprintf (header_file, "extern void * ggc_alloc_splay_tree_"); | |
4348 output_typename (header_file, s); | |
4349 oprintf (header_file, " (int, void *);\n"); | |
4350 write_splay_tree_allocator_def (s); | |
4351 } | |
4352 } | |
4353 | |
4354 static void dump_pair (int indent, pair_p p); | |
4355 static void dump_type (int indent, type_p p); | |
4356 static void dump_type_list (int indent, type_p p); | |
4357 | 4681 |
4358 #define INDENT 2 | 4682 #define INDENT 2 |
4359 | 4683 |
4360 /* Dumps the value of typekind KIND. */ | 4684 /* Dumps the value of typekind KIND. */ |
4361 | 4685 |
4371 case TYPE_STRING: | 4695 case TYPE_STRING: |
4372 printf ("TYPE_STRING"); | 4696 printf ("TYPE_STRING"); |
4373 break; | 4697 break; |
4374 case TYPE_STRUCT: | 4698 case TYPE_STRUCT: |
4375 printf ("TYPE_STRUCT"); | 4699 printf ("TYPE_STRUCT"); |
4700 break; | |
4701 case TYPE_UNDEFINED: | |
4702 printf ("TYPE_UNDEFINED"); | |
4703 break; | |
4704 case TYPE_USER_STRUCT: | |
4705 printf ("TYPE_USER_STRUCT"); | |
4376 break; | 4706 break; |
4377 case TYPE_UNION: | 4707 case TYPE_UNION: |
4378 printf ("TYPE_UNION"); | 4708 printf ("TYPE_UNION"); |
4379 break; | 4709 break; |
4380 case TYPE_POINTER: | 4710 case TYPE_POINTER: |
4383 case TYPE_ARRAY: | 4713 case TYPE_ARRAY: |
4384 printf ("TYPE_ARRAY"); | 4714 printf ("TYPE_ARRAY"); |
4385 break; | 4715 break; |
4386 case TYPE_LANG_STRUCT: | 4716 case TYPE_LANG_STRUCT: |
4387 printf ("TYPE_LANG_STRUCT"); | 4717 printf ("TYPE_LANG_STRUCT"); |
4388 break; | |
4389 case TYPE_PARAM_STRUCT: | |
4390 printf ("TYPE_PARAM_STRUCT"); | |
4391 break; | 4718 break; |
4392 default: | 4719 default: |
4393 gcc_unreachable (); | 4720 gcc_unreachable (); |
4394 } | 4721 } |
4395 printf ("\n"); | 4722 printf ("\n"); |
4467 static void | 4794 static void |
4468 dump_type_u_s (int indent, type_p t) | 4795 dump_type_u_s (int indent, type_p t) |
4469 { | 4796 { |
4470 pair_p fields; | 4797 pair_p fields; |
4471 | 4798 |
4472 gcc_assert (t->kind == TYPE_STRUCT || t->kind == TYPE_UNION | 4799 gcc_assert (union_or_struct_p (t)); |
4473 || t->kind == TYPE_LANG_STRUCT); | |
4474 printf ("%*cu.s.tag = %s\n", indent, ' ', t->u.s.tag); | 4800 printf ("%*cu.s.tag = %s\n", indent, ' ', t->u.s.tag); |
4475 dump_fileloc (indent, t->u.s.line); | 4801 dump_fileloc (indent, t->u.s.line); |
4476 printf ("%*cu.s.fields =\n", indent, ' '); | 4802 printf ("%*cu.s.fields =\n", indent, ' '); |
4477 fields = t->u.s.fields; | 4803 fields = t->u.s.fields; |
4478 while (fields) | 4804 while (fields) |
4498 gcc_assert (t->kind == TYPE_ARRAY); | 4824 gcc_assert (t->kind == TYPE_ARRAY); |
4499 printf ("%*clen = %s, u.a.p:\n", indent, ' ', t->u.a.len); | 4825 printf ("%*clen = %s, u.a.p:\n", indent, ' ', t->u.a.len); |
4500 dump_type_list (indent + INDENT, t->u.a.p); | 4826 dump_type_list (indent + INDENT, t->u.a.p); |
4501 } | 4827 } |
4502 | 4828 |
4503 /* Recursively dumps the parameterized struct T. */ | |
4504 | |
4505 static void | |
4506 dump_type_u_param_struct (int indent, type_p t) | |
4507 { | |
4508 int i; | |
4509 gcc_assert (t->kind == TYPE_PARAM_STRUCT); | |
4510 printf ("%*cu.param_struct.stru:\n", indent, ' '); | |
4511 dump_type_list (indent, t->u.param_struct.stru); | |
4512 dump_fileloc (indent, t->u.param_struct.line); | |
4513 for (i = 0; i < NUM_PARAM; i++) | |
4514 { | |
4515 if (t->u.param_struct.param[i] == NULL) | |
4516 continue; | |
4517 printf ("%*cu.param_struct.param[%d]:\n", indent, ' ', i); | |
4518 dump_type (indent + INDENT, t->u.param_struct.param[i]); | |
4519 } | |
4520 } | |
4521 | |
4522 /* Recursively dumps the type list T. */ | 4829 /* Recursively dumps the type list T. */ |
4523 | 4830 |
4524 static void | 4831 static void |
4525 dump_type_list (int indent, type_p t) | 4832 dump_type_list (int indent, type_p t) |
4526 { | 4833 { |
4540 dump_type (int indent, type_p t) | 4847 dump_type (int indent, type_p t) |
4541 { | 4848 { |
4542 PTR *slot; | 4849 PTR *slot; |
4543 | 4850 |
4544 printf ("%*cType at %p: ", indent, ' ', (void *) t); | 4851 printf ("%*cType at %p: ", indent, ' ', (void *) t); |
4852 if (t->kind == TYPE_UNDEFINED) | |
4853 { | |
4854 gcc_assert (t->gc_used == GC_UNUSED); | |
4855 printf ("undefined.\n"); | |
4856 return; | |
4857 } | |
4858 | |
4859 if (seen_types == NULL) | |
4860 seen_types = htab_create (100, htab_hash_pointer, htab_eq_pointer, NULL); | |
4861 | |
4545 slot = htab_find_slot (seen_types, t, INSERT); | 4862 slot = htab_find_slot (seen_types, t, INSERT); |
4546 if (*slot != NULL) | 4863 if (*slot != NULL) |
4547 { | 4864 { |
4548 printf ("already seen.\n"); | 4865 printf ("already seen.\n"); |
4549 return; | 4866 return; |
4564 case TYPE_STRING: | 4881 case TYPE_STRING: |
4565 break; | 4882 break; |
4566 case TYPE_STRUCT: | 4883 case TYPE_STRUCT: |
4567 case TYPE_UNION: | 4884 case TYPE_UNION: |
4568 case TYPE_LANG_STRUCT: | 4885 case TYPE_LANG_STRUCT: |
4886 case TYPE_USER_STRUCT: | |
4569 dump_type_u_s (indent + INDENT, t); | 4887 dump_type_u_s (indent + INDENT, t); |
4570 break; | 4888 break; |
4571 case TYPE_POINTER: | 4889 case TYPE_POINTER: |
4572 printf ("%*cp:\n", indent + INDENT, ' '); | 4890 printf ("%*cp:\n", indent + INDENT, ' '); |
4573 dump_type (indent + INDENT, t->u.p); | 4891 dump_type (indent + INDENT, t->u.p); |
4574 break; | 4892 break; |
4575 case TYPE_ARRAY: | 4893 case TYPE_ARRAY: |
4576 dump_type_u_a (indent + INDENT, t); | 4894 dump_type_u_a (indent + INDENT, t); |
4577 break; | 4895 break; |
4578 case TYPE_PARAM_STRUCT: | |
4579 dump_type_u_param_struct (indent + INDENT, t); | |
4580 break; | |
4581 default: | 4896 default: |
4582 gcc_unreachable (); | 4897 gcc_unreachable (); |
4583 } | 4898 } |
4584 printf ("%*cEnd of type at %p\n", indent, ' ', (void *) t); | 4899 printf ("%*cEnd of type at %p\n", indent, ' ', (void *) t); |
4585 } | 4900 } |
4623 developers. */ | 4938 developers. */ |
4624 | 4939 |
4625 static void | 4940 static void |
4626 dump_everything (void) | 4941 dump_everything (void) |
4627 { | 4942 { |
4628 seen_types = htab_create (100, htab_hash_pointer, htab_eq_pointer, NULL); | |
4629 dump_pair_list ("typedefs", typedefs); | 4943 dump_pair_list ("typedefs", typedefs); |
4630 dump_structures ("structures", structures); | 4944 dump_structures ("structures", structures); |
4631 dump_structures ("param_structs", param_structs); | |
4632 dump_pair_list ("variables", variables); | 4945 dump_pair_list ("variables", variables); |
4946 | |
4947 /* Allocated with the first call to dump_type. */ | |
4633 htab_delete (seen_types); | 4948 htab_delete (seen_types); |
4634 } | 4949 } |
4635 | 4950 |
4636 | 4951 |
4637 | 4952 |
4786 return NULL; | 5101 return NULL; |
4787 namlen = strlen (name); | 5102 namlen = strlen (name); |
4788 f = XCNEWVAR (input_file, sizeof (input_file)+namlen+2); | 5103 f = XCNEWVAR (input_file, sizeof (input_file)+namlen+2); |
4789 f->inpbitmap = 0; | 5104 f->inpbitmap = 0; |
4790 f->inpoutf = NULL; | 5105 f->inpoutf = NULL; |
5106 f->inpisplugin = false; | |
4791 strcpy (f->inpname, name); | 5107 strcpy (f->inpname, name); |
4792 slot = htab_find_slot (input_file_htab, f, INSERT); | 5108 slot = htab_find_slot (input_file_htab, f, INSERT); |
4793 gcc_assert (slot != NULL); | 5109 gcc_assert (slot != NULL); |
4794 if (*slot) | 5110 if (*slot) |
4795 { | 5111 { |
4815 htab_eq_inputfile (const void *x, const void *y) | 5131 htab_eq_inputfile (const void *x, const void *y) |
4816 { | 5132 { |
4817 const input_file *inpfx = (const input_file *) x; | 5133 const input_file *inpfx = (const input_file *) x; |
4818 const input_file *inpfy = (const input_file *) y; | 5134 const input_file *inpfy = (const input_file *) y; |
4819 gcc_assert (inpfx != NULL && inpfy != NULL); | 5135 gcc_assert (inpfx != NULL && inpfy != NULL); |
4820 return !strcmp (get_input_file_name (inpfx), get_input_file_name (inpfy)); | 5136 return !filename_cmp (get_input_file_name (inpfx), get_input_file_name (inpfy)); |
4821 } | 5137 } |
4822 | 5138 |
4823 | 5139 |
4824 int | 5140 int |
4825 main (int argc, char **argv) | 5141 main (int argc, char **argv) |
4840 scalar_nonchar.u.scalar_is_char = FALSE; | 5156 scalar_nonchar.u.scalar_is_char = FALSE; |
4841 scalar_char.u.scalar_is_char = TRUE; | 5157 scalar_char.u.scalar_is_char = TRUE; |
4842 | 5158 |
4843 parse_program_options (argc, argv); | 5159 parse_program_options (argc, argv); |
4844 | 5160 |
4845 #if ENABLE_CHECKING | |
4846 if (do_debug) | 5161 if (do_debug) |
4847 { | 5162 { |
4848 time_t now = (time_t) 0; | 5163 time_t now = (time_t) 0; |
4849 time (&now); | 5164 time (&now); |
4850 DBGPRINTF ("gengtype started pid %d at %s", | 5165 DBGPRINTF ("gengtype started pid %d at %s", |
4851 (int) getpid (), ctime (&now)); | 5166 (int) getpid (), ctime (&now)); |
4852 } | 5167 } |
4853 #endif /* ENABLE_CHECKING */ | |
4854 | 5168 |
4855 /* Parse the input list and the input files. */ | 5169 /* Parse the input list and the input files. */ |
4856 DBGPRINTF ("inputlist %s", inputlist); | 5170 DBGPRINTF ("inputlist %s", inputlist); |
4857 if (read_state_filename) | 5171 if (read_state_filename) |
4858 { | 5172 { |
4859 if (inputlist) | 5173 if (inputlist) |
4860 fatal ("input list %s cannot be given with a read state file %s", | 5174 fatal ("input list %s cannot be given with a read state file %s", |
4861 inputlist, read_state_filename); | 5175 inputlist, read_state_filename); |
4862 read_state (read_state_filename); | 5176 read_state (read_state_filename); |
4863 DBGPRINT_COUNT_TYPE ("structures after read_state", structures); | 5177 DBGPRINT_COUNT_TYPE ("structures after read_state", structures); |
4864 DBGPRINT_COUNT_TYPE ("param_structs after read_state", param_structs); | |
4865 } | 5178 } |
4866 else if (inputlist) | 5179 else if (inputlist) |
4867 { | 5180 { |
4868 /* These types are set up with #define or else outside of where | 5181 /* These types are set up with #define or else outside of where |
4869 we can see them. We should initialize them before calling | 5182 we can see them. We should initialize them before calling |
4870 read_input_list. */ | 5183 read_input_list. */ |
4871 #define POS_HERE(Call) do { pos.file = this_file; pos.line = __LINE__; \ | 5184 #define POS_HERE(Call) do { pos.file = this_file; pos.line = __LINE__; \ |
4872 Call;} while(0) | 5185 Call;} while (0) |
4873 POS_HERE (do_scalar_typedef ("CUMULATIVE_ARGS", &pos)); | 5186 POS_HERE (do_scalar_typedef ("CUMULATIVE_ARGS", &pos)); |
4874 POS_HERE (do_scalar_typedef ("REAL_VALUE_TYPE", &pos)); | 5187 POS_HERE (do_scalar_typedef ("REAL_VALUE_TYPE", &pos)); |
4875 POS_HERE (do_scalar_typedef ("FIXED_VALUE_TYPE", &pos)); | 5188 POS_HERE (do_scalar_typedef ("FIXED_VALUE_TYPE", &pos)); |
4876 POS_HERE (do_scalar_typedef ("double_int", &pos)); | 5189 POS_HERE (do_scalar_typedef ("double_int", &pos)); |
5190 POS_HERE (do_scalar_typedef ("offset_int", &pos)); | |
5191 POS_HERE (do_scalar_typedef ("widest_int", &pos)); | |
5192 POS_HERE (do_scalar_typedef ("int64_t", &pos)); | |
4877 POS_HERE (do_scalar_typedef ("uint64_t", &pos)); | 5193 POS_HERE (do_scalar_typedef ("uint64_t", &pos)); |
4878 POS_HERE (do_scalar_typedef ("uint8", &pos)); | 5194 POS_HERE (do_scalar_typedef ("uint8", &pos)); |
5195 POS_HERE (do_scalar_typedef ("uintptr_t", &pos)); | |
4879 POS_HERE (do_scalar_typedef ("jword", &pos)); | 5196 POS_HERE (do_scalar_typedef ("jword", &pos)); |
4880 POS_HERE (do_scalar_typedef ("JCF_u2", &pos)); | 5197 POS_HERE (do_scalar_typedef ("JCF_u2", &pos)); |
4881 POS_HERE (do_scalar_typedef ("void", &pos)); | 5198 POS_HERE (do_scalar_typedef ("void", &pos)); |
5199 POS_HERE (do_scalar_typedef ("machine_mode", &pos)); | |
4882 POS_HERE (do_typedef ("PTR", | 5200 POS_HERE (do_typedef ("PTR", |
4883 create_pointer (resolve_typedef ("void", &pos)), | 5201 create_pointer (resolve_typedef ("void", &pos)), |
4884 &pos)); | 5202 &pos)); |
4885 #undef POS_HERE | 5203 #undef POS_HERE |
4886 read_input_list (inputlist); | 5204 read_input_list (inputlist); |
4893 if (verbosity_level >= 1) | 5211 if (verbosity_level >= 1) |
4894 printf ("%s parsed %d files with %d GTY types\n", | 5212 printf ("%s parsed %d files with %d GTY types\n", |
4895 progname, (int) num_gt_files, type_count); | 5213 progname, (int) num_gt_files, type_count); |
4896 | 5214 |
4897 DBGPRINT_COUNT_TYPE ("structures after parsing", structures); | 5215 DBGPRINT_COUNT_TYPE ("structures after parsing", structures); |
4898 DBGPRINT_COUNT_TYPE ("param_structs after parsing", param_structs); | |
4899 | |
4900 } | 5216 } |
4901 else | 5217 else |
4902 fatal ("either an input list or a read state file should be given"); | 5218 fatal ("either an input list or a read state file should be given"); |
4903 if (hit_error) | 5219 if (hit_error) |
4904 return 1; | 5220 return 1; |
4917 fatal ("No plugin files given in plugin mode for %s", | 5233 fatal ("No plugin files given in plugin mode for %s", |
4918 plugin_output_filename); | 5234 plugin_output_filename); |
4919 | 5235 |
4920 /* Parse our plugin files and augment the state. */ | 5236 /* Parse our plugin files and augment the state. */ |
4921 for (ix = 0; ix < nb_plugin_files; ix++) | 5237 for (ix = 0; ix < nb_plugin_files; ix++) |
4922 parse_file (get_input_file_name (plugin_files[ix])); | 5238 { |
4923 | 5239 input_file* pluginput = plugin_files [ix]; |
5240 pluginput->inpisplugin = true; | |
5241 parse_file (get_input_file_name (pluginput)); | |
5242 } | |
4924 if (hit_error) | 5243 if (hit_error) |
4925 return 1; | 5244 return 1; |
4926 | 5245 |
4927 plugin_output = create_file ("GCC", plugin_output_filename); | 5246 plugin_output = create_file ("GCC", plugin_output_filename); |
4928 DBGPRINTF ("created plugin_output %p named %s", | 5247 DBGPRINTF ("created plugin_output %p named %s", |
4936 if (hit_error) | 5255 if (hit_error) |
4937 return 1; | 5256 return 1; |
4938 | 5257 |
4939 gen_rtx_next (); | 5258 gen_rtx_next (); |
4940 | 5259 |
4941 /* The call to set_gc_used may indirectly call find_param_structure | |
4942 hence enlarge the param_structs list of types. */ | |
4943 set_gc_used (variables); | 5260 set_gc_used (variables); |
4944 | 5261 |
5262 for (type_p t = structures; t; t = t->next) | |
5263 { | |
5264 bool for_user = false; | |
5265 for (options_p o = t->u.s.opt; o; o = o->next) | |
5266 if (strcmp (o->name, "for_user") == 0) | |
5267 { | |
5268 for_user = true; | |
5269 break; | |
5270 } | |
5271 | |
5272 if (for_user) | |
5273 set_gc_used_type (t, GC_POINTED_TO); | |
5274 } | |
4945 /* The state at this point is read from the state input file or by | 5275 /* The state at this point is read from the state input file or by |
4946 parsing source files and optionally augmented by parsing plugin | 5276 parsing source files and optionally augmented by parsing plugin |
4947 source files. Write it now. */ | 5277 source files. Write it now. */ |
4948 if (write_state_filename) | 5278 if (write_state_filename) |
4949 { | 5279 { |
4950 DBGPRINT_COUNT_TYPE ("structures before write_state", structures); | 5280 DBGPRINT_COUNT_TYPE ("structures before write_state", structures); |
4951 DBGPRINT_COUNT_TYPE ("param_structs before write_state", param_structs); | |
4952 | 5281 |
4953 if (hit_error) | 5282 if (hit_error) |
4954 fatal ("didn't write state file %s after errors", | 5283 fatal ("didn't write state file %s after errors", |
4955 write_state_filename); | 5284 write_state_filename); |
4956 | 5285 |
4969 } | 5298 } |
4970 | 5299 |
4971 | 5300 |
4972 open_base_files (); | 5301 open_base_files (); |
4973 | 5302 |
4974 write_enum_defn (structures, param_structs); | |
4975 write_typed_alloc_defns (structures, typedefs); | |
4976 output_header = plugin_output ? plugin_output : header_file; | 5303 output_header = plugin_output ? plugin_output : header_file; |
4977 DBGPRINT_COUNT_TYPE ("structures before write_types outputheader", | 5304 DBGPRINT_COUNT_TYPE ("structures before write_types outputheader", |
4978 structures); | 5305 structures); |
4979 DBGPRINT_COUNT_TYPE ("param_structs before write_types outputheader", | 5306 |
4980 param_structs); | 5307 write_types (output_header, structures, &ggc_wtd); |
4981 | |
4982 write_types (output_header, structures, param_structs, &ggc_wtd); | |
4983 if (plugin_files == NULL) | 5308 if (plugin_files == NULL) |
4984 { | 5309 { |
4985 DBGPRINT_COUNT_TYPE ("structures before write_types headerfil", | 5310 DBGPRINT_COUNT_TYPE ("structures before write_types headerfil", |
4986 structures); | 5311 structures); |
4987 DBGPRINT_COUNT_TYPE ("param_structs before write_types headerfil", | 5312 write_types (header_file, structures, &pch_wtd); |
4988 param_structs); | 5313 write_local (header_file, structures); |
4989 write_types (header_file, structures, param_structs, &pch_wtd); | 5314 } |
4990 write_local (header_file, structures, param_structs); | |
4991 } | |
4992 write_splay_tree_allocators (param_structs); | |
4993 write_roots (variables, plugin_files == NULL); | 5315 write_roots (variables, plugin_files == NULL); |
4994 write_rtx_next (); | 5316 write_rtx_next (); |
4995 close_output_files (); | 5317 close_output_files (); |
4996 | 5318 |
4997 if (do_dump) | 5319 if (do_dump) |