1 /* Precompiled header implementation for the C languages.
2 Copyright (C) 2000, 2002 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC 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 2, or (at your option)
11 GNU CC 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 GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
23 #include "coretypes.h"
35 unsigned long asm_size;
38 static const char pch_ident[8] = "gpchC010";
40 static FILE *pch_outfile;
42 extern char *asm_file_name;
43 static long asm_file_startpos;
52 /* We're precompiling a header file, so when it's actually used,
53 it'll be at least one level deep. */
54 (*debug_hooks->start_source_file) (lineno, input_filename);
56 f = fopen (pch_file, "w+b");
58 fatal_io_error ("can't open %s", pch_file);
61 if (fwrite (pch_ident, sizeof (pch_ident), 1, f) != 1)
62 fatal_io_error ("can't write to %s", pch_file);
64 /* We need to be able to re-read the output. */
65 /* The driver always provides a valid -o option. */
66 if (asm_file_name == NULL
67 || strcmp (asm_file_name, "-") == 0)
68 fatal_error ("`%s' is not a valid output file", asm_file_name);
70 asm_file_startpos = ftell (asm_out_file);
72 cpp_save_state (parse_in, f);
82 struct c_pch_header h;
84 cpp_write_pch_deps (parse_in, pch_outfile);
86 asm_file_end = ftell (asm_out_file);
87 h.asm_size = asm_file_end - asm_file_startpos;
89 if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
90 fatal_io_error ("can't write %s", pch_file);
92 buf = xmalloc (16384);
93 fflush (asm_out_file);
95 if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
96 fatal_io_error ("can't seek in %s", asm_file_name);
98 for (written = asm_file_startpos; written < asm_file_end; )
100 long size = asm_file_end - written;
103 if (fread (buf, size, 1, asm_out_file) != 1)
104 fatal_io_error ("can't read %s", asm_file_name);
105 if (fwrite (buf, size, 1, pch_outfile) != 1)
106 fatal_io_error ("can't write %s", pch_file);
111 gt_pch_save (pch_outfile);
112 cpp_write_pch_state (parse_in, pch_outfile);
114 fclose (pch_outfile);
118 c_common_valid_pch (pfile, name, fd)
125 char ident[sizeof (pch_ident)];
130 /* Perform a quick test of whether this is a valid
131 precompiled header for C. */
133 sizeread = read (fd, ident, sizeof (pch_ident));
136 fatal_io_error ("can't read %s", name);
139 else if (sizeread != sizeof (pch_ident))
142 if (memcmp (ident, pch_ident, sizeof (pch_ident)) != 0)
144 if (cpp_get_options (pfile)->warn_invalid_pch)
146 if (memcmp (ident, pch_ident, 5) == 0)
147 /* It's a PCH, for the right language, but has the wrong version.
149 cpp_error (pfile, DL_WARNING,
150 "%s: not compatible with this GCC version", name);
151 else if (memcmp (ident, pch_ident, 4) == 0)
152 /* It's a PCH for the wrong language. */
153 cpp_error (pfile, DL_WARNING, "%s: not for C language", name);
155 /* Not any kind of PCH. */
156 cpp_error (pfile, DL_WARNING, "%s: not a PCH file", name);
161 /* Check the preprocessor macros are the same as when the PCH was
164 result = cpp_valid_state (pfile, name, fd);
172 c_common_read_pch (pfile, name, fd, orig_name)
176 const char *orig_name;
179 struct c_pch_header h;
181 unsigned long written;
182 struct save_macro_data *smd;
184 /* Before we wrote the file, we started a source file, so we have to start
185 one here to match. */
186 (*debug_hooks->start_source_file) (lineno, orig_name);
188 f = fdopen (fd, "rb");
191 cpp_errno (pfile, DL_ERROR, "calling fdopen");
197 if (fread (&h, sizeof (h), 1, f) != 1)
199 cpp_errno (pfile, DL_ERROR, "reading");
203 buf = xmalloc (16384);
204 for (written = 0; written < h.asm_size; )
206 long size = h.asm_size - written;
209 if (fread (buf, size, 1, f) != 1
210 || fwrite (buf, size, 1, asm_out_file) != 1)
211 cpp_errno (pfile, DL_ERROR, "reading");
216 cpp_prepare_state (pfile, &smd);
220 if (cpp_read_state (pfile, name, f, smd) != 0)
225 (*debug_hooks->end_source_file) (lineno);