OSDN Git Service

* typeck.c (build_x_unary_op): Take note of the fact that
[pf3gnuchains/gcc-fork.git] / gcc / c-pch.c
1 /* Precompiled header implementation for the C languages.
2    Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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 2, or (at your option)
9 any later version.
10
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.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.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
35 struct c_pch_validity
36 {
37   unsigned char debug_info_type;
38 };
39
40 struct c_pch_header 
41 {
42   unsigned long asm_size;
43 };
44
45 #define IDENT_LENGTH 8
46
47 static FILE *pch_outfile;
48
49 static long asm_file_startpos;
50
51 static const char *get_ident (void);
52
53 /* Compute an appropriate 8-byte magic number for the PCH file, so that
54    utilities like file(1) can identify it, and so that GCC can quickly
55    ignore non-PCH files and PCH files that are of a completely different
56    format.  */
57
58 static const char *
59 get_ident(void)
60 {
61   static char result[IDENT_LENGTH];
62   static const char template[IDENT_LENGTH] = "gpch.011";
63   static const char c_language_chars[] = "Co+O";
64   
65   memcpy (result, template, IDENT_LENGTH);
66   result[4] = c_language_chars[c_language];
67
68   return result;
69 }
70
71 /* Prepare to write a PCH file.  This is called at the start of 
72    compilation.  */
73
74 void
75 pch_init (void)
76 {
77   FILE *f;
78   struct c_pch_validity v;
79   
80   if (! pch_file)
81     return;
82   
83   f = fopen (pch_file, "w+b");
84   if (f == NULL)
85     fatal_error ("can't open %s: %m", pch_file);
86   pch_outfile = f;
87   
88   v.debug_info_type = write_symbols;
89   if (fwrite (get_ident(), IDENT_LENGTH, 1, f) != 1
90       || fwrite (&v, sizeof (v), 1, f) != 1)
91     fatal_error ("can't write to %s: %m", pch_file);
92
93   /* We need to be able to re-read the output.  */
94   /* The driver always provides a valid -o option.  */
95   if (asm_file_name == NULL
96       || strcmp (asm_file_name, "-") == 0)
97     fatal_error ("`%s' is not a valid output file", asm_file_name);
98   
99   asm_file_startpos = ftell (asm_out_file);
100   
101   /* Let the debugging format deal with the PCHness.  */
102   (*debug_hooks->handle_pch) (0);
103   
104   cpp_save_state (parse_in, f);
105 }
106
107 /* Write the PCH file.  This is called at the end of a compilation which
108    will produce a PCH file.  */
109
110 void
111 c_common_write_pch (void)
112 {
113   char *buf;
114   long asm_file_end;
115   long written;
116   struct c_pch_header h;
117
118   (*debug_hooks->handle_pch) (1);
119
120   cpp_write_pch_deps (parse_in, pch_outfile);
121
122   asm_file_end = ftell (asm_out_file);
123   h.asm_size = asm_file_end - asm_file_startpos;
124   
125   if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
126     fatal_error ("can't write %s: %m", pch_file);
127   
128   buf = xmalloc (16384);
129   fflush (asm_out_file);
130
131   if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
132     fatal_error ("can't seek in %s: %m", asm_file_name);
133
134   for (written = asm_file_startpos; written < asm_file_end; )
135     {
136       long size = asm_file_end - written;
137       if (size > 16384)
138         size = 16384;
139       if (fread (buf, size, 1, asm_out_file) != 1)
140         fatal_error ("can't read %s: %m", asm_file_name);
141       if (fwrite (buf, size, 1, pch_outfile) != 1)
142         fatal_error ("can't write %s: %m", pch_file);
143       written += size;
144     }
145   free (buf);
146   /* asm_out_file can be written afterwards, so must be flushed first.  */
147   fflush (asm_out_file);
148
149   gt_pch_save (pch_outfile);
150   cpp_write_pch_state (parse_in, pch_outfile);
151
152   fclose (pch_outfile);
153 }
154
155 /* Check the PCH file called NAME, open on FD, to see if it can be used
156    in this compilation.  */
157
158 int
159 c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
160 {
161   int sizeread;
162   int result;
163   char ident[IDENT_LENGTH];
164   const char *pch_ident;
165   struct c_pch_validity v;
166
167   if (! allow_pch)
168     return 2;
169
170   /* Perform a quick test of whether this is a valid
171      precompiled header for the current language.  */
172
173   sizeread = read (fd, ident, IDENT_LENGTH);
174   if (sizeread == -1)
175     fatal_error ("can't read %s: %m", name);
176   else if (sizeread != IDENT_LENGTH)
177     return 2;
178   
179   pch_ident = get_ident();
180   if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
181     {
182       if (cpp_get_options (pfile)->warn_invalid_pch)
183         {
184           if (memcmp (ident, pch_ident, 5) == 0)
185             /* It's a PCH, for the right language, but has the wrong version.
186              */
187             cpp_error (pfile, DL_WARNING, 
188                        "%s: not compatible with this GCC version", name);
189           else if (memcmp (ident, pch_ident, 4) == 0)
190             /* It's a PCH for the wrong language.  */
191             cpp_error (pfile, DL_WARNING, "%s: not for %s", name,
192                        lang_hooks.name);
193           else 
194             /* Not any kind of PCH.  */
195             cpp_error (pfile, DL_WARNING, "%s: not a PCH file", name);
196         }
197       return 2;
198     }
199
200   if (read (fd, &v, sizeof (v)) != sizeof (v))
201     fatal_error ("can't read %s: %m", name);
202
203   /* The allowable debug info combinations are that either the PCH file
204      was built with the same as is being used now, or the PCH file was
205      built for some kind of debug info but now none is in use.  */
206   if (v.debug_info_type != write_symbols
207       && write_symbols != NO_DEBUG)
208     {
209       if (cpp_get_options (pfile)->warn_invalid_pch)
210         cpp_error (pfile, DL_WARNING, 
211                    "%s: created with -g%s, but used with -g%s", name,
212                    debug_type_names[v.debug_info_type],
213                    debug_type_names[write_symbols]);
214       return 2;
215     }
216
217   /* Check the preprocessor macros are the same as when the PCH was
218      generated.  */
219   
220   result = cpp_valid_state (pfile, name, fd);
221   if (result == -1)
222     return 2;
223   else
224     return result == 0;
225 }
226
227 /* Load in the PCH file NAME, open on FD.  It was originally searched for
228    by ORIG_NAME.  */
229
230 void
231 c_common_read_pch (cpp_reader *pfile, const char *name,
232                    int fd, const char *orig_name ATTRIBUTE_UNUSED)
233 {
234   FILE *f;
235   struct c_pch_header h;
236   char *buf;
237   unsigned long written;
238   struct save_macro_data *smd;
239   
240   f = fdopen (fd, "rb");
241   if (f == NULL)
242     {
243       cpp_errno (pfile, DL_ERROR, "calling fdopen");
244       return;
245     }
246
247   allow_pch = 0;
248
249   if (fread (&h, sizeof (h), 1, f) != 1)
250     {
251       cpp_errno (pfile, DL_ERROR, "reading");
252       return;
253     }
254
255   buf = xmalloc (16384);
256   for (written = 0; written < h.asm_size; )
257     {
258       long size = h.asm_size - written;
259       if (size > 16384)
260         size = 16384;
261       if (fread (buf, size, 1, f) != 1
262           || fwrite (buf, size, 1, asm_out_file) != 1)
263         cpp_errno (pfile, DL_ERROR, "reading");
264       written += size;
265     }
266   free (buf);
267
268   cpp_prepare_state (pfile, &smd);
269
270   gt_pch_restore (f);
271
272   if (cpp_read_state (pfile, name, f, smd) != 0)
273     return;
274
275   fclose (f);
276 }