PR c++/15745
[official-gcc.git] / gcc / c-pch.c
blob255bcad20c83334b259b2d5738c2d64aba2ebf90
1 /* Precompiled header implementation for the C languages.
2 Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "version.h"
24 #include "cpplib.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "c-common.h"
28 #include "output.h"
29 #include "toplev.h"
30 #include "debug.h"
31 #include "c-pragma.h"
32 #include "ggc.h"
33 #include "langhooks.h"
34 #include "hosthooks.h"
35 #include "target.h"
37 /* This is a list of flag variables that must match exactly, and their
38 names for the error message. The possible values for *flag_var must
39 fit in a 'signed char'. */
41 static const struct c_pch_matching
43 int *flag_var;
44 const char *flag_name;
45 } pch_matching[] = {
46 { &flag_exceptions, "-fexceptions" },
47 { &flag_unit_at_a_time, "-funit-at-a-time" }
50 enum {
51 MATCH_SIZE = ARRAY_SIZE (pch_matching)
54 /* The value of the checksum in the dummy compiler that is actually
55 checksummed. That compiler should never be run. */
56 static const char no_checksum[16] = { 0 };
58 /* Information about flags and suchlike that affect PCH validity.
60 Before this structure is read, both an initial 8-character identification
61 string, and a 16-byte checksum, have been read and validated. */
63 struct c_pch_validity
65 unsigned char debug_info_type;
66 signed char match[MATCH_SIZE];
67 void (*pch_init) (void);
68 size_t target_data_length;
71 struct c_pch_header
73 unsigned long asm_size;
76 #define IDENT_LENGTH 8
78 /* The file we'll be writing the PCH to. */
79 static FILE *pch_outfile;
81 /* The position in the assembler output file when pch_init was called. */
82 static long asm_file_startpos;
84 static const char *get_ident (void);
86 /* Compute an appropriate 8-byte magic number for the PCH file, so that
87 utilities like file(1) can identify it, and so that GCC can quickly
88 ignore non-PCH files and PCH files that are of a completely different
89 format. */
91 static const char *
92 get_ident (void)
94 static char result[IDENT_LENGTH];
95 static const char template[IDENT_LENGTH] = "gpch.013";
96 static const char c_language_chars[] = "Co+O";
98 memcpy (result, template, IDENT_LENGTH);
99 result[4] = c_language_chars[c_language];
101 return result;
104 /* Prepare to write a PCH file, if one is being written. This is
105 called at the start of compilation.
107 Also, print out the executable checksum if -fverbose-asm is in effect. */
109 void
110 pch_init (void)
112 FILE *f;
113 struct c_pch_validity v;
114 void *target_validity;
115 static const char partial_pch[IDENT_LENGTH] = "gpcWrite";
117 #ifdef ASM_COMMENT_START
118 if (flag_verbose_asm)
120 fprintf (asm_out_file, "%s ", ASM_COMMENT_START);
121 c_common_print_pch_checksum (asm_out_file);
122 fputc ('\n', asm_out_file);
124 #endif
126 if (!pch_file)
127 return;
129 f = fopen (pch_file, "w+b");
130 if (f == NULL)
131 fatal_error ("can%'t create precompiled header %s: %m", pch_file);
132 pch_outfile = f;
134 gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0);
136 v.debug_info_type = write_symbols;
138 size_t i;
139 for (i = 0; i < MATCH_SIZE; i++)
141 v.match[i] = *pch_matching[i].flag_var;
142 gcc_assert (v.match[i] == *pch_matching[i].flag_var);
145 v.pch_init = &pch_init;
146 target_validity = targetm.get_pch_validity (&v.target_data_length);
148 if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
149 || fwrite (executable_checksum, 16, 1, f) != 1
150 || fwrite (&v, sizeof (v), 1, f) != 1
151 || fwrite (target_validity, v.target_data_length, 1, f) != 1)
152 fatal_error ("can%'t write to %s: %m", pch_file);
154 /* We need to be able to re-read the output. */
155 /* The driver always provides a valid -o option. */
156 if (asm_file_name == NULL
157 || strcmp (asm_file_name, "-") == 0)
158 fatal_error ("%qs is not a valid output file", asm_file_name);
160 asm_file_startpos = ftell (asm_out_file);
162 /* Let the debugging format deal with the PCHness. */
163 (*debug_hooks->handle_pch) (0);
165 cpp_save_state (parse_in, f);
168 /* Write the PCH file. This is called at the end of a compilation which
169 will produce a PCH file. */
171 void
172 c_common_write_pch (void)
174 char *buf;
175 long asm_file_end;
176 long written;
177 struct c_pch_header h;
179 (*debug_hooks->handle_pch) (1);
181 cpp_write_pch_deps (parse_in, pch_outfile);
183 asm_file_end = ftell (asm_out_file);
184 h.asm_size = asm_file_end - asm_file_startpos;
186 if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
187 fatal_error ("can%'t write %s: %m", pch_file);
189 buf = XNEWVEC (char, 16384);
191 if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
192 fatal_error ("can%'t seek in %s: %m", asm_file_name);
194 for (written = asm_file_startpos; written < asm_file_end; )
196 long size = asm_file_end - written;
197 if (size > 16384)
198 size = 16384;
199 if (fread (buf, size, 1, asm_out_file) != 1)
200 fatal_error ("can%'t read %s: %m", asm_file_name);
201 if (fwrite (buf, size, 1, pch_outfile) != 1)
202 fatal_error ("can%'t write %s: %m", pch_file);
203 written += size;
205 free (buf);
206 /* asm_out_file can be written afterwards, so fseek to clear
207 _IOREAD flag. */
208 if (fseek (asm_out_file, 0, SEEK_END) != 0)
209 fatal_error ("can%'t seek in %s: %m", asm_file_name);
211 gt_pch_save (pch_outfile);
212 cpp_write_pch_state (parse_in, pch_outfile);
214 if (fseek (pch_outfile, 0, SEEK_SET) != 0
215 || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
216 fatal_error ("can%'t write %s: %m", pch_file);
218 fclose (pch_outfile);
221 /* Check the PCH file called NAME, open on FD, to see if it can be
222 used in this compilation. Return 1 if valid, 0 if the file can't
223 be used now but might be if it's seen later in the compilation, and
224 2 if this file could never be used in the compilation. */
227 c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
229 int sizeread;
230 int result;
231 char ident[IDENT_LENGTH + 16];
232 const char *pch_ident;
233 struct c_pch_validity v;
235 /* Perform a quick test of whether this is a valid
236 precompiled header for the current language. */
238 gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0);
240 sizeread = read (fd, ident, IDENT_LENGTH + 16);
241 if (sizeread == -1)
242 fatal_error ("can%'t read %s: %m", name);
243 else if (sizeread != IDENT_LENGTH + 16)
245 cpp_error (pfile, CPP_DL_WARNING, "%s: too short to be a PCH file",
246 name);
247 return 2;
250 pch_ident = get_ident();
251 if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
253 if (cpp_get_options (pfile)->warn_invalid_pch)
255 if (memcmp (ident, pch_ident, 5) == 0)
256 /* It's a PCH, for the right language, but has the wrong version.
258 cpp_error (pfile, CPP_DL_WARNING,
259 "%s: not compatible with this GCC version", name);
260 else if (memcmp (ident, pch_ident, 4) == 0)
261 /* It's a PCH for the wrong language. */
262 cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
263 lang_hooks.name);
264 else
265 /* Not any kind of PCH. */
266 cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
268 return 2;
270 if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
272 if (cpp_get_options (pfile)->warn_invalid_pch)
273 cpp_error (pfile, CPP_DL_WARNING,
274 "%s: created by a different GCC executable", name);
275 return 2;
278 /* At this point, we know it's a PCH file created by this
279 executable, so it ought to be long enough that we can read a
280 c_pch_validity structure. */
281 if (read (fd, &v, sizeof (v)) != sizeof (v))
282 fatal_error ("can%'t read %s: %m", name);
284 /* The allowable debug info combinations are that either the PCH file
285 was built with the same as is being used now, or the PCH file was
286 built for some kind of debug info but now none is in use. */
287 if (v.debug_info_type != write_symbols
288 && write_symbols != NO_DEBUG)
290 if (cpp_get_options (pfile)->warn_invalid_pch)
291 cpp_error (pfile, CPP_DL_WARNING,
292 "%s: created with -g%s, but used with -g%s", name,
293 debug_type_names[v.debug_info_type],
294 debug_type_names[write_symbols]);
295 return 2;
298 /* Check flags that must match exactly. */
300 size_t i;
301 for (i = 0; i < MATCH_SIZE; i++)
302 if (*pch_matching[i].flag_var != v.match[i])
304 if (cpp_get_options (pfile)->warn_invalid_pch)
305 cpp_error (pfile, CPP_DL_WARNING,
306 "%s: settings for %s do not match", name,
307 pch_matching[i].flag_name);
308 return 2;
312 /* If the text segment was not loaded at the same address as it was
313 when the PCH file was created, function pointers loaded from the
314 PCH will not be valid. We could in theory remap all the function
315 pointers, but no support for that exists at present.
316 Since we have the same executable, it should only be necessary to
317 check one function. */
318 if (v.pch_init != &pch_init)
320 if (cpp_get_options (pfile)->warn_invalid_pch)
321 cpp_error (pfile, CPP_DL_WARNING,
322 "%s: had text segment at different address", name);
323 return 2;
326 /* Check the target-specific validity data. */
328 void *this_file_data = xmalloc (v.target_data_length);
329 const char *msg;
331 if ((size_t) read (fd, this_file_data, v.target_data_length)
332 != v.target_data_length)
333 fatal_error ("can%'t read %s: %m", name);
334 msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
335 free (this_file_data);
336 if (msg != NULL)
338 if (cpp_get_options (pfile)->warn_invalid_pch)
339 cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
340 return 2;
344 /* Check the preprocessor macros are the same as when the PCH was
345 generated. */
347 result = cpp_valid_state (pfile, name, fd);
348 if (result == -1)
349 return 2;
350 else
351 return result == 0;
354 /* If non-NULL, this function is called after a precompile header file
355 is loaded. */
356 void (*lang_post_pch_load) (void);
358 /* Load in the PCH file NAME, open on FD. It was originally searched for
359 by ORIG_NAME. */
361 void
362 c_common_read_pch (cpp_reader *pfile, const char *name,
363 int fd, const char *orig_name ATTRIBUTE_UNUSED)
365 FILE *f;
366 struct c_pch_header h;
367 struct save_macro_data *smd;
369 f = fdopen (fd, "rb");
370 if (f == NULL)
372 cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
373 return;
376 cpp_get_callbacks (parse_in)->valid_pch = NULL;
378 if (fread (&h, sizeof (h), 1, f) != 1)
380 cpp_errno (pfile, CPP_DL_ERROR, "reading");
381 return;
384 if (!flag_preprocess_only)
386 unsigned long written;
387 char * buf = XNEWVEC (char, 16384);
389 for (written = 0; written < h.asm_size; )
391 long size = h.asm_size - written;
392 if (size > 16384)
393 size = 16384;
394 if (fread (buf, size, 1, f) != 1
395 || fwrite (buf, size, 1, asm_out_file) != 1)
396 cpp_errno (pfile, CPP_DL_ERROR, "reading");
397 written += size;
399 free (buf);
401 else
403 /* If we're preprocessing, don't write to a NULL
404 asm_out_file. */
405 if (fseek (f, h.asm_size, SEEK_CUR) != 0)
406 cpp_errno (pfile, CPP_DL_ERROR, "seeking");
409 cpp_prepare_state (pfile, &smd);
411 gt_pch_restore (f);
413 if (cpp_read_state (pfile, name, f, smd) != 0)
414 return;
416 fclose (f);
418 /* Give the front end a chance to take action after a PCH file has
419 been loaded. */
420 if (lang_post_pch_load)
421 (*lang_post_pch_load) ();
424 /* Indicate that no more PCH files should be read. */
426 void
427 c_common_no_more_pch (void)
429 if (cpp_get_callbacks (parse_in)->valid_pch)
431 cpp_get_callbacks (parse_in)->valid_pch = NULL;
432 host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
436 /* Handle #pragma GCC pch_preprocess, to load in the PCH file. */
438 #ifndef O_BINARY
439 # define O_BINARY 0
440 #endif
442 void
443 c_common_pch_pragma (cpp_reader *pfile, const char *name)
445 int fd;
447 if (!cpp_get_options (pfile)->preprocessed)
449 error ("pch_preprocess pragma should only be used with -fpreprocessed");
450 inform ("use #include instead");
451 return;
454 fd = open (name, O_RDONLY | O_BINARY, 0666);
455 if (fd == -1)
456 fatal_error ("%s: couldn%'t open PCH file: %m", name);
458 if (c_common_valid_pch (pfile, name, fd) != 1)
460 if (!cpp_get_options (pfile)->warn_invalid_pch)
461 inform ("use -Winvalid-pch for more information");
462 fatal_error ("%s: PCH file was invalid", name);
465 c_common_read_pch (pfile, name, fd, name);
467 close (fd);
470 /* Print out executable_checksum[]. */
472 void
473 c_common_print_pch_checksum (FILE *f)
475 int i;
476 fputs ("Compiler executable checksum: ", f);
477 for (i = 0; i < 16; i++)
478 fprintf (f, "%02x", executable_checksum[i]);
479 putc ('\n', f);