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