Mercurial > hg > CbC > CbC_gcc
comparison gcc/c-family/c-pch.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | 561a7518be6b |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Precompiled header implementation for the C languages. | 1 /* Precompiled header implementation for the C languages. |
2 Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 | 2 Copyright (C) 2000-2017 Free Software Foundation, Inc. |
3 Free Software Foundation, Inc. | |
4 | 3 |
5 This file is part of GCC. | 4 This file is part of GCC. |
6 | 5 |
7 GCC is free software; you can redistribute it and/or modify | 6 GCC is free software; you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
19 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
20 | 19 |
21 #include "config.h" | 20 #include "config.h" |
22 #include "system.h" | 21 #include "system.h" |
23 #include "coretypes.h" | 22 #include "coretypes.h" |
24 #include "version.h" | 23 #include "target.h" |
25 #include "cpplib.h" | 24 #include "c-common.h" |
26 #include "tree.h" | 25 #include "timevar.h" |
27 #include "flags.h" | 26 #include "flags.h" |
28 #include "c-common.h" | |
29 #include "output.h" | |
30 #include "debug.h" | 27 #include "debug.h" |
31 #include "c-pragma.h" | 28 #include "c-pragma.h" |
32 #include "ggc.h" | |
33 #include "langhooks.h" | 29 #include "langhooks.h" |
34 #include "hosthooks.h" | 30 #include "hosthooks.h" |
35 #include "target.h" | |
36 #include "opts.h" | |
37 #include "timevar.h" | |
38 | 31 |
39 /* This is a list of flag variables that must match exactly, and their | 32 /* This is a list of flag variables that must match exactly, and their |
40 names for the error message. The possible values for *flag_var must | 33 names for the error message. The possible values for *flag_var must |
41 fit in a 'signed char'. */ | 34 fit in a 'signed char'. */ |
42 | 35 |
67 signed char match[MATCH_SIZE]; | 60 signed char match[MATCH_SIZE]; |
68 void (*pch_init) (void); | 61 void (*pch_init) (void); |
69 size_t target_data_length; | 62 size_t target_data_length; |
70 }; | 63 }; |
71 | 64 |
72 struct c_pch_header | |
73 { | |
74 unsigned long asm_size; | |
75 }; | |
76 | |
77 #define IDENT_LENGTH 8 | 65 #define IDENT_LENGTH 8 |
78 | 66 |
79 /* The file we'll be writing the PCH to. */ | 67 /* The file we'll be writing the PCH to. */ |
80 static FILE *pch_outfile; | 68 static FILE *pch_outfile; |
81 | |
82 /* The position in the assembler output file when pch_init was called. */ | |
83 static long asm_file_startpos; | |
84 | 69 |
85 static const char *get_ident (void); | 70 static const char *get_ident (void); |
86 | 71 |
87 /* Compute an appropriate 8-byte magic number for the PCH file, so that | 72 /* Compute an appropriate 8-byte magic number for the PCH file, so that |
88 utilities like file(1) can identify it, and so that GCC can quickly | 73 utilities like file(1) can identify it, and so that GCC can quickly |
91 | 76 |
92 static const char * | 77 static const char * |
93 get_ident (void) | 78 get_ident (void) |
94 { | 79 { |
95 static char result[IDENT_LENGTH]; | 80 static char result[IDENT_LENGTH]; |
96 static const char templ[] = "gpch.013"; | 81 static const char templ[] = "gpch.014"; |
97 static const char c_language_chars[] = "Co+O"; | 82 static const char c_language_chars[] = "Co+O"; |
98 | 83 |
99 memcpy (result, templ, IDENT_LENGTH); | 84 memcpy (result, templ, IDENT_LENGTH); |
100 result[4] = c_language_chars[c_language]; | 85 result[4] = c_language_chars[c_language]; |
101 | 86 |
102 return result; | 87 return result; |
103 } | 88 } |
104 | 89 |
90 /* Whether preprocessor state should be saved by pch_init. */ | |
91 | |
92 static bool pch_ready_to_save_cpp_state = false; | |
93 | |
105 /* Prepare to write a PCH file, if one is being written. This is | 94 /* Prepare to write a PCH file, if one is being written. This is |
106 called at the start of compilation. | 95 called at the start of compilation. */ |
107 | |
108 Also, print out the executable checksum if -fverbose-asm is in effect. */ | |
109 | 96 |
110 void | 97 void |
111 pch_init (void) | 98 pch_init (void) |
112 { | 99 { |
113 FILE *f; | 100 FILE *f; |
114 struct c_pch_validity v; | 101 struct c_pch_validity v; |
115 void *target_validity; | 102 void *target_validity; |
116 static const char partial_pch[] = "gpcWrite"; | 103 static const char partial_pch[] = "gpcWrite"; |
117 | 104 |
118 #ifdef ASM_COMMENT_START | |
119 if (flag_verbose_asm) | |
120 { | |
121 fprintf (asm_out_file, "%s ", ASM_COMMENT_START); | |
122 c_common_print_pch_checksum (asm_out_file); | |
123 fputc ('\n', asm_out_file); | |
124 } | |
125 #endif | |
126 | |
127 if (!pch_file) | 105 if (!pch_file) |
128 return; | 106 return; |
129 | 107 |
130 f = fopen (pch_file, "w+b"); | 108 f = fopen (pch_file, "w+b"); |
131 if (f == NULL) | 109 if (f == NULL) |
132 fatal_error ("can%'t create precompiled header %s: %m", pch_file); | 110 fatal_error (input_location, "can%'t create precompiled header %s: %m", |
111 pch_file); | |
133 pch_outfile = f; | 112 pch_outfile = f; |
134 | 113 |
135 gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0); | 114 gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0); |
136 | 115 |
137 memset (&v, '\0', sizeof (v)); | 116 memset (&v, '\0', sizeof (v)); |
149 | 128 |
150 if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1 | 129 if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1 |
151 || fwrite (executable_checksum, 16, 1, f) != 1 | 130 || fwrite (executable_checksum, 16, 1, f) != 1 |
152 || fwrite (&v, sizeof (v), 1, f) != 1 | 131 || fwrite (&v, sizeof (v), 1, f) != 1 |
153 || fwrite (target_validity, v.target_data_length, 1, f) != 1) | 132 || fwrite (target_validity, v.target_data_length, 1, f) != 1) |
154 fatal_error ("can%'t write to %s: %m", pch_file); | 133 fatal_error (input_location, "can%'t write to %s: %m", pch_file); |
155 | |
156 /* We need to be able to re-read the output. */ | |
157 /* The driver always provides a valid -o option. */ | |
158 if (asm_file_name == NULL | |
159 || strcmp (asm_file_name, "-") == 0) | |
160 fatal_error ("%qs is not a valid output file", asm_file_name); | |
161 | |
162 asm_file_startpos = ftell (asm_out_file); | |
163 | 134 |
164 /* Let the debugging format deal with the PCHness. */ | 135 /* Let the debugging format deal with the PCHness. */ |
165 (*debug_hooks->handle_pch) (0); | 136 (*debug_hooks->handle_pch) (0); |
166 | 137 |
167 cpp_save_state (parse_in, f); | 138 if (pch_ready_to_save_cpp_state) |
139 pch_cpp_save_state (); | |
140 | |
141 XDELETE (target_validity); | |
142 } | |
143 | |
144 /* Whether preprocessor state has been saved in a PCH file. */ | |
145 | |
146 static bool pch_cpp_state_saved = false; | |
147 | |
148 /* Save preprocessor state in a PCH file, after implicitly included | |
149 headers have been read. If the PCH file has not yet been opened, | |
150 record that state should be saved when it is opened. */ | |
151 | |
152 void | |
153 pch_cpp_save_state (void) | |
154 { | |
155 if (!pch_cpp_state_saved) | |
156 { | |
157 if (pch_outfile) | |
158 { | |
159 cpp_save_state (parse_in, pch_outfile); | |
160 pch_cpp_state_saved = true; | |
161 } | |
162 else | |
163 pch_ready_to_save_cpp_state = true; | |
164 } | |
168 } | 165 } |
169 | 166 |
170 /* Write the PCH file. This is called at the end of a compilation which | 167 /* Write the PCH file. This is called at the end of a compilation which |
171 will produce a PCH file. */ | 168 will produce a PCH file. */ |
172 | 169 |
173 void | 170 void |
174 c_common_write_pch (void) | 171 c_common_write_pch (void) |
175 { | 172 { |
176 char *buf; | |
177 long asm_file_end; | |
178 long written; | |
179 struct c_pch_header h; | |
180 | |
181 timevar_push (TV_PCH_SAVE); | 173 timevar_push (TV_PCH_SAVE); |
182 | 174 |
175 targetm.prepare_pch_save (); | |
176 | |
183 (*debug_hooks->handle_pch) (1); | 177 (*debug_hooks->handle_pch) (1); |
184 | 178 |
179 prepare_target_option_nodes_for_pch (); | |
180 | |
185 cpp_write_pch_deps (parse_in, pch_outfile); | 181 cpp_write_pch_deps (parse_in, pch_outfile); |
186 | |
187 asm_file_end = ftell (asm_out_file); | |
188 h.asm_size = asm_file_end - asm_file_startpos; | |
189 | |
190 if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1) | |
191 fatal_error ("can%'t write %s: %m", pch_file); | |
192 | |
193 buf = XNEWVEC (char, 16384); | |
194 | |
195 if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0) | |
196 fatal_error ("can%'t seek in %s: %m", asm_file_name); | |
197 | |
198 for (written = asm_file_startpos; written < asm_file_end; ) | |
199 { | |
200 long size = asm_file_end - written; | |
201 if (size > 16384) | |
202 size = 16384; | |
203 if (fread (buf, size, 1, asm_out_file) != 1) | |
204 fatal_error ("can%'t read %s: %m", asm_file_name); | |
205 if (fwrite (buf, size, 1, pch_outfile) != 1) | |
206 fatal_error ("can%'t write %s: %m", pch_file); | |
207 written += size; | |
208 } | |
209 free (buf); | |
210 /* asm_out_file can be written afterwards, so fseek to clear | |
211 _IOREAD flag. */ | |
212 if (fseek (asm_out_file, 0, SEEK_END) != 0) | |
213 fatal_error ("can%'t seek in %s: %m", asm_file_name); | |
214 | 182 |
215 gt_pch_save (pch_outfile); | 183 gt_pch_save (pch_outfile); |
216 | 184 |
217 timevar_push (TV_PCH_CPP_SAVE); | 185 timevar_push (TV_PCH_CPP_SAVE); |
218 cpp_write_pch_state (parse_in, pch_outfile); | 186 cpp_write_pch_state (parse_in, pch_outfile); |
219 timevar_pop (TV_PCH_CPP_SAVE); | 187 timevar_pop (TV_PCH_CPP_SAVE); |
220 | 188 |
221 if (fseek (pch_outfile, 0, SEEK_SET) != 0 | 189 if (fseek (pch_outfile, 0, SEEK_SET) != 0 |
222 || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1) | 190 || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1) |
223 fatal_error ("can%'t write %s: %m", pch_file); | 191 fatal_error (input_location, "can%'t write %s: %m", pch_file); |
224 | 192 |
225 fclose (pch_outfile); | 193 fclose (pch_outfile); |
226 | 194 |
227 timevar_pop (TV_PCH_SAVE); | 195 timevar_pop (TV_PCH_SAVE); |
228 } | 196 } |
246 | 214 |
247 gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0); | 215 gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0); |
248 | 216 |
249 sizeread = read (fd, ident, IDENT_LENGTH + 16); | 217 sizeread = read (fd, ident, IDENT_LENGTH + 16); |
250 if (sizeread == -1) | 218 if (sizeread == -1) |
251 fatal_error ("can%'t read %s: %m", name); | 219 fatal_error (input_location, "can%'t read %s: %m", name); |
252 else if (sizeread != IDENT_LENGTH + 16) | 220 else if (sizeread != IDENT_LENGTH + 16) |
253 { | 221 { |
254 if (cpp_get_options (pfile)->warn_invalid_pch) | 222 if (cpp_get_options (pfile)->warn_invalid_pch) |
255 cpp_error (pfile, CPP_DL_WARNING, "%s: too short to be a PCH file", | 223 cpp_error (pfile, CPP_DL_WARNING, "%s: too short to be a PCH file", |
256 name); | 224 name); |
287 | 255 |
288 /* At this point, we know it's a PCH file created by this | 256 /* At this point, we know it's a PCH file created by this |
289 executable, so it ought to be long enough that we can read a | 257 executable, so it ought to be long enough that we can read a |
290 c_pch_validity structure. */ | 258 c_pch_validity structure. */ |
291 if (read (fd, &v, sizeof (v)) != sizeof (v)) | 259 if (read (fd, &v, sizeof (v)) != sizeof (v)) |
292 fatal_error ("can%'t read %s: %m", name); | 260 fatal_error (input_location, "can%'t read %s: %m", name); |
293 | 261 |
294 /* The allowable debug info combinations are that either the PCH file | 262 /* The allowable debug info combinations are that either the PCH file |
295 was built with the same as is being used now, or the PCH file was | 263 was built with the same as is being used now, or the PCH file was |
296 built for some kind of debug info but now none is in use. */ | 264 built for some kind of debug info but now none is in use. */ |
297 if (v.debug_info_type != write_symbols | 265 if (v.debug_info_type != write_symbols |
338 void *this_file_data = xmalloc (v.target_data_length); | 306 void *this_file_data = xmalloc (v.target_data_length); |
339 const char *msg; | 307 const char *msg; |
340 | 308 |
341 if ((size_t) read (fd, this_file_data, v.target_data_length) | 309 if ((size_t) read (fd, this_file_data, v.target_data_length) |
342 != v.target_data_length) | 310 != v.target_data_length) |
343 fatal_error ("can%'t read %s: %m", name); | 311 fatal_error (input_location, "can%'t read %s: %m", name); |
344 msg = targetm.pch_valid_p (this_file_data, v.target_data_length); | 312 msg = targetm.pch_valid_p (this_file_data, v.target_data_length); |
345 free (this_file_data); | 313 free (this_file_data); |
346 if (msg != NULL) | 314 if (msg != NULL) |
347 { | 315 { |
348 if (cpp_get_options (pfile)->warn_invalid_pch) | 316 if (cpp_get_options (pfile)->warn_invalid_pch) |
371 void | 339 void |
372 c_common_read_pch (cpp_reader *pfile, const char *name, | 340 c_common_read_pch (cpp_reader *pfile, const char *name, |
373 int fd, const char *orig_name ATTRIBUTE_UNUSED) | 341 int fd, const char *orig_name ATTRIBUTE_UNUSED) |
374 { | 342 { |
375 FILE *f; | 343 FILE *f; |
376 struct c_pch_header h; | |
377 struct save_macro_data *smd; | 344 struct save_macro_data *smd; |
378 expanded_location saved_loc; | 345 expanded_location saved_loc; |
379 bool saved_trace_includes; | 346 bool saved_trace_includes; |
380 | 347 |
381 timevar_push (TV_PCH_RESTORE); | 348 timevar_push (TV_PCH_RESTORE); |
388 goto end; | 355 goto end; |
389 } | 356 } |
390 | 357 |
391 cpp_get_callbacks (parse_in)->valid_pch = NULL; | 358 cpp_get_callbacks (parse_in)->valid_pch = NULL; |
392 | 359 |
393 if (fread (&h, sizeof (h), 1, f) != 1) | |
394 { | |
395 cpp_errno (pfile, CPP_DL_ERROR, "reading"); | |
396 fclose (f); | |
397 goto end; | |
398 } | |
399 | |
400 if (!flag_preprocess_only) | |
401 { | |
402 unsigned long written; | |
403 char * buf = XNEWVEC (char, 16384); | |
404 | |
405 for (written = 0; written < h.asm_size; ) | |
406 { | |
407 long size = h.asm_size - written; | |
408 if (size > 16384) | |
409 size = 16384; | |
410 if (fread (buf, size, 1, f) != 1 | |
411 || fwrite (buf, size, 1, asm_out_file) != 1) | |
412 cpp_errno (pfile, CPP_DL_ERROR, "reading"); | |
413 written += size; | |
414 } | |
415 free (buf); | |
416 } | |
417 else | |
418 { | |
419 /* If we're preprocessing, don't write to a NULL | |
420 asm_out_file. */ | |
421 if (fseek (f, h.asm_size, SEEK_CUR) != 0) | |
422 cpp_errno (pfile, CPP_DL_ERROR, "seeking"); | |
423 } | |
424 | |
425 /* Save the location and then restore it after reading the PCH. */ | 360 /* Save the location and then restore it after reading the PCH. */ |
426 saved_loc = expand_location (line_table->highest_line); | 361 saved_loc = expand_location (line_table->highest_line); |
427 saved_trace_includes = line_table->trace_includes; | 362 saved_trace_includes = line_table->trace_includes; |
428 | 363 |
429 timevar_push (TV_PCH_CPP_RESTORE); | 364 timevar_push (TV_PCH_CPP_RESTORE); |
430 cpp_prepare_state (pfile, &smd); | 365 cpp_prepare_state (pfile, &smd); |
431 timevar_pop (TV_PCH_CPP_RESTORE); | 366 timevar_pop (TV_PCH_CPP_RESTORE); |
432 | 367 |
433 gt_pch_restore (f); | 368 gt_pch_restore (f); |
369 cpp_set_line_map (pfile, line_table); | |
370 rebuild_location_adhoc_htab (line_table); | |
434 | 371 |
435 timevar_push (TV_PCH_CPP_RESTORE); | 372 timevar_push (TV_PCH_CPP_RESTORE); |
436 if (cpp_read_state (pfile, name, f, smd) != 0) | 373 if (cpp_read_state (pfile, name, f, smd) != 0) |
437 { | 374 { |
438 fclose (f); | 375 fclose (f); |
443 | 380 |
444 | 381 |
445 fclose (f); | 382 fclose (f); |
446 | 383 |
447 line_table->trace_includes = saved_trace_includes; | 384 line_table->trace_includes = saved_trace_includes; |
448 cpp_set_line_map (pfile, line_table); | 385 linemap_add (line_table, LC_ENTER, 0, saved_loc.file, saved_loc.line); |
449 linemap_add (line_table, LC_RENAME, 0, saved_loc.file, saved_loc.line); | |
450 | 386 |
451 /* Give the front end a chance to take action after a PCH file has | 387 /* Give the front end a chance to take action after a PCH file has |
452 been loaded. */ | 388 been loaded. */ |
453 if (lang_post_pch_load) | 389 if (lang_post_pch_load) |
454 (*lang_post_pch_load) (); | 390 (*lang_post_pch_load) (); |
483 return; | 419 return; |
484 } | 420 } |
485 | 421 |
486 fd = open (name, O_RDONLY | O_BINARY, 0666); | 422 fd = open (name, O_RDONLY | O_BINARY, 0666); |
487 if (fd == -1) | 423 if (fd == -1) |
488 fatal_error ("%s: couldn%'t open PCH file: %m", name); | 424 fatal_error (input_location, "%s: couldn%'t open PCH file: %m", name); |
489 | 425 |
490 if (c_common_valid_pch (pfile, name, fd) != 1) | 426 if (c_common_valid_pch (pfile, name, fd) != 1) |
491 { | 427 { |
492 if (!cpp_get_options (pfile)->warn_invalid_pch) | 428 if (!cpp_get_options (pfile)->warn_invalid_pch) |
493 inform (input_location, "use -Winvalid-pch for more information"); | 429 inform (input_location, "use -Winvalid-pch for more information"); |
494 fatal_error ("%s: PCH file was invalid", name); | 430 fatal_error (input_location, "%s: PCH file was invalid", name); |
495 } | 431 } |
496 | 432 |
497 c_common_read_pch (pfile, name, fd, name); | 433 c_common_read_pch (pfile, name, fd, name); |
498 | 434 |
499 close (fd); | 435 close (fd); |
500 } | 436 } |
501 | 437 |
502 /* Print out executable_checksum[]. */ | |
503 | |
504 void | |
505 c_common_print_pch_checksum (FILE *f) | |
506 { | |
507 int i; | |
508 fputs ("Compiler executable checksum: ", f); | |
509 for (i = 0; i < 16; i++) | |
510 fprintf (f, "%02x", executable_checksum[i]); | |
511 putc ('\n', f); | |
512 } |