FSF GCC merge 02/23/03
[official-gcc.git] / gcc / c-pch.c
blob13dc7631798db247ab93a7824ac7808c541546d1
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)
9 any later version.
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. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "cpplib.h"
25 #include "tree.h"
26 #include "c-common.h"
27 #include "output.h"
28 #include "toplev.h"
29 #include "debug.h"
30 #include "c-pragma.h"
31 #include "ggc.h"
33 struct c_pch_header
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;
45 void
46 pch_init ()
48 FILE *f;
50 if (pch_file)
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");
57 if (f == NULL)
58 fatal_io_error ("can't open %s", pch_file);
59 pch_outfile = f;
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);
76 void
77 c_common_write_pch ()
79 char *buf;
80 long asm_file_end;
81 long written;
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;
101 if (size > 16384)
102 size = 16384;
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);
107 written += size;
109 free (buf);
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)
119 cpp_reader *pfile;
120 const char *name;
121 int fd;
123 int sizeread;
124 int result;
125 char ident[sizeof (pch_ident)];
127 if (! allow_pch)
128 return 2;
130 /* Perform a quick test of whether this is a valid
131 precompiled header for C. */
133 sizeread = read (fd, ident, sizeof (pch_ident));
134 if (sizeread == -1)
136 fatal_io_error ("can't read %s", name);
137 return 2;
139 else if (sizeread != sizeof (pch_ident))
140 return 2;
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);
154 else
155 /* Not any kind of PCH. */
156 cpp_error (pfile, DL_WARNING, "%s: not a PCH file", name);
158 return 2;
161 /* Check the preprocessor macros are the same as when the PCH was
162 generated. */
164 result = cpp_valid_state (pfile, name, fd);
165 if (result == -1)
166 return 2;
167 else
168 return result == 0;
171 void
172 c_common_read_pch (pfile, name, fd, orig_name)
173 cpp_reader *pfile;
174 const char *name;
175 int fd;
176 const char *orig_name;
178 FILE *f;
179 struct c_pch_header h;
180 char *buf;
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");
189 if (f == NULL)
191 cpp_errno (pfile, DL_ERROR, "calling fdopen");
192 return;
195 allow_pch = 0;
197 if (fread (&h, sizeof (h), 1, f) != 1)
199 cpp_errno (pfile, DL_ERROR, "reading");
200 return;
203 buf = xmalloc (16384);
204 for (written = 0; written < h.asm_size; )
206 long size = h.asm_size - written;
207 if (size > 16384)
208 size = 16384;
209 if (fread (buf, size, 1, f) != 1
210 || fwrite (buf, size, 1, asm_out_file) != 1)
211 cpp_errno (pfile, DL_ERROR, "reading");
212 written += size;
214 free (buf);
216 cpp_prepare_state (pfile, &smd);
218 gt_pch_restore (f);
220 if (cpp_read_state (pfile, name, f, smd) != 0)
221 return;
223 fclose (f);
225 (*debug_hooks->end_source_file) (lineno);