OSDN Git Service

* config/frv/frv.h: Remove declaration of g_switch_value.
[pf3gnuchains/gcc-fork.git] / gcc / c-pch.c
1 /* Precompiled header implementation for the C languages.
2    Copyright (C) 2000, 2002 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 PARAMS((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()
60 {
61   static char result[IDENT_LENGTH];
62   static const char template[IDENT_LENGTH] = "gpch.011";
63   
64   memcpy (result, template, IDENT_LENGTH);
65   if (c_language == clk_c)
66     result[4] = flag_objc ? 'o' : 'C';
67   else if (c_language == clk_cplusplus)
68     result[4] = flag_objc ? 'O' : '+';
69   else
70     abort ();
71   return result;
72 }
73
74 /* Prepare to write a PCH file.  This is called at the start of 
75    compilation.  */
76
77 void
78 pch_init ()
79 {
80   FILE *f;
81   struct c_pch_validity v;
82   
83   if (! pch_file)
84     return;
85   
86   f = fopen (pch_file, "w+b");
87   if (f == NULL)
88     fatal_error ("can't open %s: %m", pch_file);
89   pch_outfile = f;
90   
91   v.debug_info_type = write_symbols;
92   if (fwrite (get_ident(), IDENT_LENGTH, 1, f) != 1
93       || fwrite (&v, sizeof (v), 1, f) != 1)
94     fatal_error ("can't write to %s: %m", pch_file);
95
96   /* We need to be able to re-read the output.  */
97   /* The driver always provides a valid -o option.  */
98   if (asm_file_name == NULL
99       || strcmp (asm_file_name, "-") == 0)
100     fatal_error ("`%s' is not a valid output file", asm_file_name);
101   
102   asm_file_startpos = ftell (asm_out_file);
103   
104   /* Let the debugging format deal with the PCHness.  */
105   (*debug_hooks->handle_pch) (0);
106   
107   cpp_save_state (parse_in, f);
108 }
109
110 /* Write the PCH file.  This is called at the end of a compilation which
111    will produce a PCH file.  */
112
113 void
114 c_common_write_pch ()
115 {
116   char *buf;
117   long asm_file_end;
118   long written;
119   struct c_pch_header h;
120
121   (*debug_hooks->handle_pch) (1);
122
123   cpp_write_pch_deps (parse_in, pch_outfile);
124
125   asm_file_end = ftell (asm_out_file);
126   h.asm_size = asm_file_end - asm_file_startpos;
127   
128   if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
129     fatal_error ("can't write %s: %m", pch_file);
130   
131   buf = xmalloc (16384);
132   fflush (asm_out_file);
133
134   if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
135     fatal_error ("can't seek in %s: %m", asm_file_name);
136
137   for (written = asm_file_startpos; written < asm_file_end; )
138     {
139       long size = asm_file_end - written;
140       if (size > 16384)
141         size = 16384;
142       if (fread (buf, size, 1, asm_out_file) != 1)
143         fatal_error ("can't read %s: %m", asm_file_name);
144       if (fwrite (buf, size, 1, pch_outfile) != 1)
145         fatal_error ("can't write %s: %m", pch_file);
146       written += size;
147     }
148   free (buf);
149
150   gt_pch_save (pch_outfile);
151   cpp_write_pch_state (parse_in, pch_outfile);
152
153   fclose (pch_outfile);
154 }
155
156 /* Check the PCH file called NAME, open on FD, to see if it can be used
157    in this compilation.  */
158
159 int
160 c_common_valid_pch (pfile, name, fd)
161      cpp_reader *pfile;
162      const char *name;
163      int fd;
164 {
165   int sizeread;
166   int result;
167   char ident[IDENT_LENGTH];
168   const char *pch_ident;
169   struct c_pch_validity v;
170
171   if (! allow_pch)
172     return 2;
173
174   /* Perform a quick test of whether this is a valid
175      precompiled header for the current language.  */
176
177   sizeread = read (fd, ident, IDENT_LENGTH);
178   if (sizeread == -1)
179     fatal_error ("can't read %s: %m", name);
180   else if (sizeread != IDENT_LENGTH)
181     return 2;
182   
183   pch_ident = get_ident();
184   if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
185     {
186       if (cpp_get_options (pfile)->warn_invalid_pch)
187         {
188           if (memcmp (ident, pch_ident, 5) == 0)
189             /* It's a PCH, for the right language, but has the wrong version.
190              */
191             cpp_error (pfile, DL_WARNING, 
192                        "%s: not compatible with this GCC version", name);
193           else if (memcmp (ident, pch_ident, 4) == 0)
194             /* It's a PCH for the wrong language.  */
195             cpp_error (pfile, DL_WARNING, "%s: not for %s", name,
196                        lang_hooks.name);
197           else 
198             /* Not any kind of PCH.  */
199             cpp_error (pfile, DL_WARNING, "%s: not a PCH file", name);
200         }
201       return 2;
202     }
203
204   if (read (fd, &v, sizeof (v)) != sizeof (v))
205     fatal_error ("can't read %s: %m", name);
206
207   /* The allowable debug info combinations are that either the PCH file
208      was built with the same as is being used now, or the PCH file was
209      built for some kind of debug info but now none is in use.  */
210   if (v.debug_info_type != write_symbols
211       && write_symbols != NO_DEBUG)
212     {
213       if (cpp_get_options (pfile)->warn_invalid_pch)
214         cpp_error (pfile, DL_WARNING, 
215                    "%s: created with -g%s, but used with -g%s", name,
216                    debug_type_names[v.debug_info_type],
217                    debug_type_names[write_symbols]);
218       return 2;
219     }
220
221   /* Check the preprocessor macros are the same as when the PCH was
222      generated.  */
223   
224   result = cpp_valid_state (pfile, name, fd);
225   if (result == -1)
226     return 2;
227   else
228     return result == 0;
229 }
230
231 /* Load in the PCH file NAME, open on FD.  It was originally searched for
232    by ORIG_NAME.  */
233
234 void
235 c_common_read_pch (pfile, name, fd, orig_name)
236      cpp_reader *pfile;
237      const char *name;
238      int fd;
239      const char *orig_name ATTRIBUTE_UNUSED;
240 {
241   FILE *f;
242   struct c_pch_header h;
243   char *buf;
244   unsigned long written;
245   struct save_macro_data *smd;
246   
247   f = fdopen (fd, "rb");
248   if (f == NULL)
249     {
250       cpp_errno (pfile, DL_ERROR, "calling fdopen");
251       return;
252     }
253
254   allow_pch = 0;
255
256   if (fread (&h, sizeof (h), 1, f) != 1)
257     {
258       cpp_errno (pfile, DL_ERROR, "reading");
259       return;
260     }
261
262   buf = xmalloc (16384);
263   for (written = 0; written < h.asm_size; )
264     {
265       long size = h.asm_size - written;
266       if (size > 16384)
267         size = 16384;
268       if (fread (buf, size, 1, f) != 1
269           || fwrite (buf, size, 1, asm_out_file) != 1)
270         cpp_errno (pfile, DL_ERROR, "reading");
271       written += size;
272     }
273   free (buf);
274
275   cpp_prepare_state (pfile, &smd);
276
277   gt_pch_restore (f);
278
279   if (cpp_read_state (pfile, name, f, smd) != 0)
280     return;
281
282   fclose (f);
283 }