]>
Commit | Line | Data |
---|---|---|
17211ab5 | 1 | /* Precompiled header implementation for the C languages. |
7adcbafe | 2 | Copyright (C) 2000-2022 Free Software Foundation, Inc. |
17211ab5 | 3 | |
54a7b573 | 4 | This file is part of GCC. |
17211ab5 | 5 | |
54a7b573 | 6 | GCC is free software; you can redistribute it and/or modify |
17211ab5 | 7 | it under the terms of the GNU General Public License as published by |
9dcd6f09 | 8 | the Free Software Foundation; either version 3, or (at your option) |
17211ab5 GK |
9 | any later version. |
10 | ||
54a7b573 | 11 | GCC is distributed in the hope that it will be useful, |
17211ab5 GK |
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 | |
9dcd6f09 NC |
17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ | |
17211ab5 GK |
19 | |
20 | #include "config.h" | |
21 | #include "system.h" | |
22 | #include "coretypes.h" | |
2adfab87 | 23 | #include "target.h" |
2adfab87 AM |
24 | #include "c-common.h" |
25 | #include "timevar.h" | |
df026186 | 26 | #include "flags.h" |
17211ab5 GK |
27 | #include "debug.h" |
28 | #include "c-pragma.h" | |
8643e92d | 29 | #include "langhooks.h" |
18c81520 | 30 | #include "hosthooks.h" |
17211ab5 | 31 | |
54e109ed GK |
32 | /* This is a list of flag variables that must match exactly, and their |
33 | names for the error message. The possible values for *flag_var must | |
34 | fit in a 'signed char'. */ | |
35 | ||
c22cacf3 | 36 | static const struct c_pch_matching |
54e109ed GK |
37 | { |
38 | int *flag_var; | |
39 | const char *flag_name; | |
40 | } pch_matching[] = { | |
41 | { &flag_exceptions, "-fexceptions" }, | |
54e109ed GK |
42 | }; |
43 | ||
44 | enum { | |
45 | MATCH_SIZE = ARRAY_SIZE (pch_matching) | |
46 | }; | |
47 | ||
3fd30b88 | 48 | /* Information about flags and suchlike that affect PCH validity. |
7bb1ad93 | 49 | |
3fd30b88 GK |
50 | Before this structure is read, both an initial 8-character identification |
51 | string, and a 16-byte checksum, have been read and validated. */ | |
7451756f | 52 | |
df026186 GK |
53 | struct c_pch_validity |
54 | { | |
459d84e9 | 55 | uint32_t pch_write_symbols; |
54e109ed | 56 | signed char match[MATCH_SIZE]; |
7bb1ad93 | 57 | size_t target_data_length; |
df026186 GK |
58 | }; |
59 | ||
8643e92d | 60 | #define IDENT_LENGTH 8 |
17211ab5 | 61 | |
7451756f | 62 | /* The file we'll be writing the PCH to. */ |
17211ab5 GK |
63 | static FILE *pch_outfile; |
64 | ||
2f6e4e97 | 65 | static const char *get_ident (void); |
8643e92d | 66 | |
df026186 GK |
67 | /* Compute an appropriate 8-byte magic number for the PCH file, so that |
68 | utilities like file(1) can identify it, and so that GCC can quickly | |
69 | ignore non-PCH files and PCH files that are of a completely different | |
70 | format. */ | |
71 | ||
8643e92d | 72 | static const char * |
3f75a254 | 73 | get_ident (void) |
8643e92d GK |
74 | { |
75 | static char result[IDENT_LENGTH]; | |
8ca92d04 | 76 | static const char templ[] = "gpch.014"; |
37fa72e9 | 77 | static const char c_language_chars[] = "Co+O"; |
c22cacf3 | 78 | |
48c54229 | 79 | memcpy (result, templ, IDENT_LENGTH); |
37fa72e9 NB |
80 | result[4] = c_language_chars[c_language]; |
81 | ||
8643e92d GK |
82 | return result; |
83 | } | |
84 | ||
1efcb8c6 JM |
85 | /* Whether preprocessor state should be saved by pch_init. */ |
86 | ||
87 | static bool pch_ready_to_save_cpp_state = false; | |
88 | ||
3fd30b88 | 89 | /* Prepare to write a PCH file, if one is being written. This is |
ee7b28eb | 90 | called at the start of compilation. */ |
df026186 | 91 | |
17211ab5 | 92 | void |
2f6e4e97 | 93 | pch_init (void) |
17211ab5 GK |
94 | { |
95 | FILE *f; | |
df026186 | 96 | struct c_pch_validity v; |
7bb1ad93 | 97 | void *target_validity; |
5eb4df45 | 98 | static const char partial_pch[] = "gpcWrite"; |
c22cacf3 | 99 | |
3f75a254 | 100 | if (!pch_file) |
df026186 | 101 | return; |
c22cacf3 | 102 | |
df026186 GK |
103 | f = fopen (pch_file, "w+b"); |
104 | if (f == NULL) | |
a9c697b8 | 105 | fatal_error (input_location, "cannot create precompiled header %s: %m", |
40fecdd6 | 106 | pch_file); |
df026186 | 107 | pch_outfile = f; |
366de0ce | 108 | |
ed5bdeb6 | 109 | memset (&v, '\0', sizeof (v)); |
459d84e9 | 110 | v.pch_write_symbols = write_symbols; |
54e109ed GK |
111 | { |
112 | size_t i; | |
113 | for (i = 0; i < MATCH_SIZE; i++) | |
114 | { | |
115 | v.match[i] = *pch_matching[i].flag_var; | |
366de0ce | 116 | gcc_assert (v.match[i] == *pch_matching[i].flag_var); |
54e109ed GK |
117 | } |
118 | } | |
7bb1ad93 | 119 | target_validity = targetm.get_pch_validity (&v.target_data_length); |
c22cacf3 | 120 | |
7a681365 | 121 | if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1 |
3fd30b88 | 122 | || fwrite (executable_checksum, 16, 1, f) != 1 |
7451756f | 123 | || fwrite (&v, sizeof (v), 1, f) != 1 |
7bb1ad93 | 124 | || fwrite (target_validity, v.target_data_length, 1, f) != 1) |
a9c697b8 | 125 | fatal_error (input_location, "cannot write to %s: %m", pch_file); |
df026186 | 126 | |
df026186 GK |
127 | /* Let the debugging format deal with the PCHness. */ |
128 | (*debug_hooks->handle_pch) (0); | |
c22cacf3 | 129 | |
1efcb8c6 JM |
130 | if (pch_ready_to_save_cpp_state) |
131 | pch_cpp_save_state (); | |
0b50e654 JJ |
132 | |
133 | XDELETE (target_validity); | |
1efcb8c6 JM |
134 | } |
135 | ||
136 | /* Whether preprocessor state has been saved in a PCH file. */ | |
137 | ||
138 | static bool pch_cpp_state_saved = false; | |
139 | ||
140 | /* Save preprocessor state in a PCH file, after implicitly included | |
141 | headers have been read. If the PCH file has not yet been opened, | |
142 | record that state should be saved when it is opened. */ | |
143 | ||
144 | void | |
145 | pch_cpp_save_state (void) | |
146 | { | |
147 | if (!pch_cpp_state_saved) | |
148 | { | |
149 | if (pch_outfile) | |
150 | { | |
151 | cpp_save_state (parse_in, pch_outfile); | |
152 | pch_cpp_state_saved = true; | |
153 | } | |
154 | else | |
155 | pch_ready_to_save_cpp_state = true; | |
156 | } | |
17211ab5 GK |
157 | } |
158 | ||
df026186 GK |
159 | /* Write the PCH file. This is called at the end of a compilation which |
160 | will produce a PCH file. */ | |
161 | ||
17211ab5 | 162 | void |
2f6e4e97 | 163 | c_common_write_pch (void) |
17211ab5 | 164 | { |
10d43c2d DN |
165 | timevar_push (TV_PCH_SAVE); |
166 | ||
e32ea2d1 RS |
167 | targetm.prepare_pch_save (); |
168 | ||
33b49800 GK |
169 | (*debug_hooks->handle_pch) (1); |
170 | ||
e83b8e2e JJ |
171 | prepare_target_option_nodes_for_pch (); |
172 | ||
17211ab5 GK |
173 | cpp_write_pch_deps (parse_in, pch_outfile); |
174 | ||
17211ab5 | 175 | gt_pch_save (pch_outfile); |
10d43c2d DN |
176 | |
177 | timevar_push (TV_PCH_CPP_SAVE); | |
17211ab5 | 178 | cpp_write_pch_state (parse_in, pch_outfile); |
10d43c2d | 179 | timevar_pop (TV_PCH_CPP_SAVE); |
17211ab5 | 180 | |
7a681365 GK |
181 | if (fseek (pch_outfile, 0, SEEK_SET) != 0 |
182 | || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1) | |
a9c697b8 | 183 | fatal_error (input_location, "cannot write %s: %m", pch_file); |
7a681365 | 184 | |
17211ab5 | 185 | fclose (pch_outfile); |
10d43c2d DN |
186 | |
187 | timevar_pop (TV_PCH_SAVE); | |
17211ab5 GK |
188 | } |
189 | ||
7bb1ad93 GK |
190 | /* Check the PCH file called NAME, open on FD, to see if it can be |
191 | used in this compilation. Return 1 if valid, 0 if the file can't | |
192 | be used now but might be if it's seen later in the compilation, and | |
193 | 2 if this file could never be used in the compilation. */ | |
df026186 | 194 | |
17211ab5 | 195 | int |
2f6e4e97 | 196 | c_common_valid_pch (cpp_reader *pfile, const char *name, int fd) |
17211ab5 GK |
197 | { |
198 | int sizeread; | |
199 | int result; | |
3fd30b88 | 200 | char ident[IDENT_LENGTH + 16]; |
8643e92d | 201 | const char *pch_ident; |
df026186 | 202 | struct c_pch_validity v; |
17211ab5 | 203 | |
17211ab5 | 204 | /* Perform a quick test of whether this is a valid |
df026186 | 205 | precompiled header for the current language. */ |
17211ab5 | 206 | |
10ee6da6 NS |
207 | /* C++ modules and PCH don't play together. */ |
208 | if (flag_modules) | |
209 | return 2; | |
210 | ||
3fd30b88 | 211 | sizeread = read (fd, ident, IDENT_LENGTH + 16); |
17211ab5 | 212 | if (sizeread == -1) |
a9c697b8 | 213 | fatal_error (input_location, "cannot read %s: %m", name); |
3fd30b88 GK |
214 | else if (sizeread != IDENT_LENGTH + 16) |
215 | { | |
cb808c58 | 216 | cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: too short to be a PCH file", |
bb1f73c2 | 217 | name); |
3fd30b88 GK |
218 | return 2; |
219 | } | |
c22cacf3 | 220 | |
8643e92d GK |
221 | pch_ident = get_ident(); |
222 | if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0) | |
17211ab5 | 223 | { |
cb808c58 NG |
224 | if (memcmp (ident, pch_ident, 5) == 0) |
225 | /* It's a PCH, for the right language, but has the wrong version. */ | |
226 | cpp_warning (pfile, CPP_W_INVALID_PCH, | |
17211ab5 | 227 | "%s: not compatible with this GCC version", name); |
cb808c58 NG |
228 | else if (memcmp (ident, pch_ident, 4) == 0) |
229 | /* It's a PCH for the wrong language. */ | |
230 | cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not for %s", name, | |
8643e92d | 231 | lang_hooks.name); |
cb808c58 NG |
232 | else |
233 | /* Not any kind of PCH. */ | |
234 | cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not a PCH file", name); | |
17211ab5 GK |
235 | return 2; |
236 | } | |
3fd30b88 | 237 | if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0) |
7451756f | 238 | { |
cb808c58 | 239 | cpp_warning (pfile, CPP_W_INVALID_PCH, |
3fd30b88 | 240 | "%s: created by a different GCC executable", name); |
7451756f GK |
241 | return 2; |
242 | } | |
243 | ||
3fd30b88 GK |
244 | /* At this point, we know it's a PCH file created by this |
245 | executable, so it ought to be long enough that we can read a | |
246 | c_pch_validity structure. */ | |
247 | if (read (fd, &v, sizeof (v)) != sizeof (v)) | |
a9c697b8 | 248 | fatal_error (input_location, "cannot read %s: %m", name); |
3fd30b88 | 249 | |
df026186 GK |
250 | /* The allowable debug info combinations are that either the PCH file |
251 | was built with the same as is being used now, or the PCH file was | |
252 | built for some kind of debug info but now none is in use. */ | |
459d84e9 | 253 | if (v.pch_write_symbols != write_symbols |
df026186 GK |
254 | && write_symbols != NO_DEBUG) |
255 | { | |
a87efd32 IB |
256 | char *created_str = xstrdup (debug_set_names (v.pch_write_symbols)); |
257 | char *used_str = xstrdup (debug_set_names (write_symbols)); | |
cb808c58 | 258 | cpp_warning (pfile, CPP_W_INVALID_PCH, |
459d84e9 | 259 | "%s: created with '%s' debug info, but used with '%s'", name, |
a87efd32 IB |
260 | created_str, used_str); |
261 | free (created_str); | |
262 | free (used_str); | |
df026186 GK |
263 | return 2; |
264 | } | |
265 | ||
54e109ed GK |
266 | /* Check flags that must match exactly. */ |
267 | { | |
268 | size_t i; | |
269 | for (i = 0; i < MATCH_SIZE; i++) | |
270 | if (*pch_matching[i].flag_var != v.match[i]) | |
271 | { | |
cb808c58 | 272 | cpp_warning (pfile, CPP_W_INVALID_PCH, |
54e109ed GK |
273 | "%s: settings for %s do not match", name, |
274 | pch_matching[i].flag_name); | |
275 | return 2; | |
276 | } | |
277 | } | |
278 | ||
7bb1ad93 GK |
279 | /* Check the target-specific validity data. */ |
280 | { | |
281 | void *this_file_data = xmalloc (v.target_data_length); | |
282 | const char *msg; | |
c22cacf3 | 283 | |
7bb1ad93 GK |
284 | if ((size_t) read (fd, this_file_data, v.target_data_length) |
285 | != v.target_data_length) | |
a9c697b8 | 286 | fatal_error (input_location, "cannot read %s: %m", name); |
7bb1ad93 GK |
287 | msg = targetm.pch_valid_p (this_file_data, v.target_data_length); |
288 | free (this_file_data); | |
289 | if (msg != NULL) | |
290 | { | |
cb808c58 | 291 | cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: %s", name, msg); |
7bb1ad93 GK |
292 | return 2; |
293 | } | |
294 | } | |
295 | ||
17211ab5 GK |
296 | /* Check the preprocessor macros are the same as when the PCH was |
297 | generated. */ | |
c22cacf3 | 298 | |
17211ab5 GK |
299 | result = cpp_valid_state (pfile, name, fd); |
300 | if (result == -1) | |
301 | return 2; | |
302 | else | |
303 | return result == 0; | |
304 | } | |
305 | ||
4684cd27 MM |
306 | /* If non-NULL, this function is called after a precompile header file |
307 | is loaded. */ | |
308 | void (*lang_post_pch_load) (void); | |
309 | ||
df026186 GK |
310 | /* Load in the PCH file NAME, open on FD. It was originally searched for |
311 | by ORIG_NAME. */ | |
312 | ||
17211ab5 | 313 | void |
2f6e4e97 AJ |
314 | c_common_read_pch (cpp_reader *pfile, const char *name, |
315 | int fd, const char *orig_name ATTRIBUTE_UNUSED) | |
17211ab5 GK |
316 | { |
317 | FILE *f; | |
17211ab5 | 318 | struct save_macro_data *smd; |
5ffeb913 | 319 | expanded_location saved_loc; |
b3e200e1 | 320 | bool saved_trace_includes; |
c22cacf3 | 321 | |
10d43c2d DN |
322 | timevar_push (TV_PCH_RESTORE); |
323 | ||
17211ab5 GK |
324 | f = fdopen (fd, "rb"); |
325 | if (f == NULL) | |
326 | { | |
0527bc4e | 327 | cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen"); |
d4c32e1d | 328 | close (fd); |
10d43c2d | 329 | goto end; |
17211ab5 GK |
330 | } |
331 | ||
18c81520 | 332 | cpp_get_callbacks (parse_in)->valid_pch = NULL; |
17211ab5 | 333 | |
5ffeb913 | 334 | /* Save the location and then restore it after reading the PCH. */ |
5ffeb913 | 335 | saved_loc = expand_location (line_table->highest_line); |
b3e200e1 | 336 | saved_trace_includes = line_table->trace_includes; |
5ffeb913 | 337 | |
10d43c2d | 338 | timevar_push (TV_PCH_CPP_RESTORE); |
17211ab5 | 339 | cpp_prepare_state (pfile, &smd); |
10d43c2d | 340 | timevar_pop (TV_PCH_CPP_RESTORE); |
17211ab5 GK |
341 | |
342 | gt_pch_restore (f); | |
671d9f12 | 343 | cpp_set_line_map (pfile, line_table); |
52187008 | 344 | rebuild_location_adhoc_htab (line_table); |
17211ab5 | 345 | |
10d43c2d | 346 | timevar_push (TV_PCH_CPP_RESTORE); |
17211ab5 | 347 | if (cpp_read_state (pfile, name, f, smd) != 0) |
d4c32e1d JJ |
348 | { |
349 | fclose (f); | |
10d43c2d DN |
350 | timevar_pop (TV_PCH_CPP_RESTORE); |
351 | goto end; | |
d4c32e1d | 352 | } |
10d43c2d DN |
353 | timevar_pop (TV_PCH_CPP_RESTORE); |
354 | ||
17211ab5 GK |
355 | |
356 | fclose (f); | |
c22cacf3 | 357 | |
b3e200e1 | 358 | line_table->trace_includes = saved_trace_includes; |
892a371f | 359 | linemap_add (line_table, LC_ENTER, 0, saved_loc.file, saved_loc.line); |
5ffeb913 | 360 | |
4684cd27 | 361 | /* Give the front end a chance to take action after a PCH file has |
6cb38cd4 | 362 | been loaded. */ |
4684cd27 MM |
363 | if (lang_post_pch_load) |
364 | (*lang_post_pch_load) (); | |
10d43c2d DN |
365 | |
366 | end: | |
367 | timevar_pop (TV_PCH_RESTORE); | |
17211ab5 | 368 | } |
18c81520 GK |
369 | |
370 | /* Indicate that no more PCH files should be read. */ | |
371 | ||
372 | void | |
373 | c_common_no_more_pch (void) | |
374 | { | |
375 | if (cpp_get_callbacks (parse_in)->valid_pch) | |
376 | { | |
377 | cpp_get_callbacks (parse_in)->valid_pch = NULL; | |
747380f4 JJ |
378 | void *addr = NULL; |
379 | host_hooks.gt_pch_use_address (addr, 0, -1, 0); | |
18c81520 GK |
380 | } |
381 | } | |
c0d578e6 GK |
382 | |
383 | /* Handle #pragma GCC pch_preprocess, to load in the PCH file. */ | |
384 | ||
c0d578e6 | 385 | void |
bc4071dd | 386 | c_common_pch_pragma (cpp_reader *pfile, const char *name) |
c0d578e6 | 387 | { |
c0d578e6 GK |
388 | int fd; |
389 | ||
3f75a254 | 390 | if (!cpp_get_options (pfile)->preprocessed) |
c0d578e6 | 391 | { |
a9c697b8 | 392 | error ("%<pch_preprocess%> pragma should only be used " |
a3f9f006 | 393 | "with %<-fpreprocessed%>"); |
a9c697b8 | 394 | inform (input_location, "use %<#include%> instead"); |
c0d578e6 GK |
395 | return; |
396 | } | |
397 | ||
c0d578e6 GK |
398 | fd = open (name, O_RDONLY | O_BINARY, 0666); |
399 | if (fd == -1) | |
40fecdd6 | 400 | fatal_error (input_location, "%s: couldn%'t open PCH file: %m", name); |
c22cacf3 | 401 | |
c0d578e6 GK |
402 | if (c_common_valid_pch (pfile, name, fd) != 1) |
403 | { | |
404 | if (!cpp_get_options (pfile)->warn_invalid_pch) | |
a3f9f006 | 405 | inform (input_location, "use %<-Winvalid-pch%> for more information"); |
40fecdd6 | 406 | fatal_error (input_location, "%s: PCH file was invalid", name); |
c0d578e6 | 407 | } |
c22cacf3 | 408 | |
c0d578e6 | 409 | c_common_read_pch (pfile, name, fd, name); |
c22cacf3 | 410 | |
c0d578e6 GK |
411 | close (fd); |
412 | } | |
3fd30b88 | 413 |