rust: build failure after NON_DEPENDENT_EXPR removal [PR111899]
[official-gcc.git] / gcc / c-family / c-pch.cc
blob2f014fca210bba63e59efc2b5c03746f6099c144
1 /* Precompiled header implementation for the C languages.
2 Copyright (C) 2000-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
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 3, or (at your option)
9 any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "target.h"
24 #include "c-common.h"
25 #include "timevar.h"
26 #include "flags.h"
27 #include "debug.h"
28 #include "c-pragma.h"
29 #include "langhooks.h"
30 #include "hosthooks.h"
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'. */
36 static const struct c_pch_matching
38 int *flag_var;
39 const char *flag_name;
40 } pch_matching[] = {
41 { &flag_exceptions, "-fexceptions" },
44 enum {
45 MATCH_SIZE = ARRAY_SIZE (pch_matching)
48 /* Information about flags and suchlike that affect PCH validity.
50 Before this structure is read, both an initial 8-character identification
51 string, and a 16-byte checksum, have been read and validated. */
53 struct c_pch_validity
55 uint32_t pch_write_symbols;
56 signed char match[MATCH_SIZE];
57 size_t target_data_length;
60 #define IDENT_LENGTH 8
62 /* The file we'll be writing the PCH to. */
63 static FILE *pch_outfile;
65 static const char *get_ident (void);
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. */
72 static const char *
73 get_ident (void)
75 static char result[IDENT_LENGTH];
76 static const char templ[] = "gpch.014";
77 static const char c_language_chars[] = "Co+O";
79 memcpy (result, templ, IDENT_LENGTH);
80 result[4] = c_language_chars[c_language];
82 return result;
85 /* Whether preprocessor state should be saved by pch_init. */
87 static bool pch_ready_to_save_cpp_state = false;
89 /* Prepare to write a PCH file, if one is being written. This is
90 called at the start of compilation. */
92 void
93 pch_init (void)
95 FILE *f;
96 struct c_pch_validity v;
97 void *target_validity;
98 static const char partial_pch[] = "gpcWrite";
100 if (!pch_file)
101 return;
103 f = fopen (pch_file, "w+b");
104 if (f == NULL)
105 fatal_error (input_location, "cannot create precompiled header %s: %m",
106 pch_file);
107 pch_outfile = f;
109 memset (&v, '\0', sizeof (v));
110 v.pch_write_symbols = write_symbols;
112 size_t i;
113 for (i = 0; i < MATCH_SIZE; i++)
115 v.match[i] = *pch_matching[i].flag_var;
116 gcc_assert (v.match[i] == *pch_matching[i].flag_var);
119 target_validity = targetm.get_pch_validity (&v.target_data_length);
121 if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
122 || fwrite (executable_checksum, 16, 1, f) != 1
123 || fwrite (&v, sizeof (v), 1, f) != 1
124 || fwrite (target_validity, v.target_data_length, 1, f) != 1)
125 fatal_error (input_location, "cannot write to %s: %m", pch_file);
127 /* Let the debugging format deal with the PCHness. */
128 (*debug_hooks->handle_pch) (0);
130 if (pch_ready_to_save_cpp_state)
131 pch_cpp_save_state ();
133 XDELETE (target_validity);
136 /* Whether preprocessor state has been saved in a PCH file. */
138 static bool pch_cpp_state_saved = false;
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. */
144 void
145 pch_cpp_save_state (void)
147 if (!pch_cpp_state_saved)
149 if (pch_outfile)
151 cpp_save_state (parse_in, pch_outfile);
152 pch_cpp_state_saved = true;
154 else
155 pch_ready_to_save_cpp_state = true;
159 /* Write the PCH file. This is called at the end of a compilation which
160 will produce a PCH file. */
162 void
163 c_common_write_pch (void)
165 timevar_push (TV_PCH_SAVE);
167 targetm.prepare_pch_save ();
169 (*debug_hooks->handle_pch) (1);
171 prepare_target_option_nodes_for_pch ();
173 cpp_write_pch_deps (parse_in, pch_outfile);
175 gt_pch_save (pch_outfile);
177 timevar_push (TV_PCH_CPP_SAVE);
178 cpp_write_pch_state (parse_in, pch_outfile);
179 timevar_pop (TV_PCH_CPP_SAVE);
181 if (fseek (pch_outfile, 0, SEEK_SET) != 0
182 || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
183 fatal_error (input_location, "cannot write %s: %m", pch_file);
185 fclose (pch_outfile);
187 timevar_pop (TV_PCH_SAVE);
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. */
196 c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
198 int sizeread;
199 int result;
200 char ident[IDENT_LENGTH + 16];
201 const char *pch_ident;
202 struct c_pch_validity v;
204 /* Perform a quick test of whether this is a valid
205 precompiled header for the current language. */
207 /* C++ modules and PCH don't play together. */
208 if (flag_modules)
209 return 2;
211 sizeread = read (fd, ident, IDENT_LENGTH + 16);
212 if (sizeread == -1)
213 fatal_error (input_location, "cannot read %s: %m", name);
214 else if (sizeread != IDENT_LENGTH + 16)
216 cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: too short to be a PCH file",
217 name);
218 return 2;
221 pch_ident = get_ident();
222 if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
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,
227 "%s: not compatible with this GCC version", name);
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,
231 lang_hooks.name);
232 else
233 /* Not any kind of PCH. */
234 cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not a PCH file", name);
235 return 2;
237 if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
239 cpp_warning (pfile, CPP_W_INVALID_PCH,
240 "%s: created by a different GCC executable", name);
241 return 2;
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))
248 fatal_error (input_location, "cannot read %s: %m", name);
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. */
253 if (v.pch_write_symbols != write_symbols
254 && write_symbols != NO_DEBUG)
256 char *created_str = xstrdup (debug_set_names (v.pch_write_symbols));
257 char *used_str = xstrdup (debug_set_names (write_symbols));
258 cpp_warning (pfile, CPP_W_INVALID_PCH,
259 "%s: created with '%s' debug info, but used with '%s'", name,
260 created_str, used_str);
261 free (created_str);
262 free (used_str);
263 return 2;
266 /* Check flags that must match exactly. */
268 size_t i;
269 for (i = 0; i < MATCH_SIZE; i++)
270 if (*pch_matching[i].flag_var != v.match[i])
272 cpp_warning (pfile, CPP_W_INVALID_PCH,
273 "%s: settings for %s do not match", name,
274 pch_matching[i].flag_name);
275 return 2;
279 /* Check the target-specific validity data. */
281 void *this_file_data = xmalloc (v.target_data_length);
282 const char *msg;
284 if ((size_t) read (fd, this_file_data, v.target_data_length)
285 != v.target_data_length)
286 fatal_error (input_location, "cannot read %s: %m", name);
287 msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
288 free (this_file_data);
289 if (msg != NULL)
291 cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: %s", name, msg);
292 return 2;
296 /* Check the preprocessor macros are the same as when the PCH was
297 generated. */
299 result = cpp_valid_state (pfile, name, fd);
300 if (result == -1)
301 return 2;
302 else
303 return result == 0;
306 /* If non-NULL, this function is called after a precompile header file
307 is loaded. */
308 void (*lang_post_pch_load) (void);
310 /* Load in the PCH file NAME, open on FD. It was originally searched for
311 by ORIG_NAME. */
313 void
314 c_common_read_pch (cpp_reader *pfile, const char *name,
315 int fd, const char *orig_name ATTRIBUTE_UNUSED)
317 FILE *f;
318 struct save_macro_data *smd;
319 expanded_location saved_loc;
320 bool saved_trace_includes;
322 timevar_push (TV_PCH_RESTORE);
324 f = fdopen (fd, "rb");
325 if (f == NULL)
327 cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
328 close (fd);
329 goto end;
332 cpp_get_callbacks (parse_in)->valid_pch = NULL;
334 /* Save the location and then restore it after reading the PCH. */
335 saved_loc = expand_location (line_table->highest_line);
336 saved_trace_includes = line_table->trace_includes;
338 timevar_push (TV_PCH_CPP_RESTORE);
339 cpp_prepare_state (pfile, &smd);
340 timevar_pop (TV_PCH_CPP_RESTORE);
342 gt_pch_restore (f);
343 cpp_set_line_map (pfile, line_table);
344 rebuild_location_adhoc_htab (line_table);
346 timevar_push (TV_PCH_CPP_RESTORE);
347 if (cpp_read_state (pfile, name, f, smd) != 0)
349 fclose (f);
350 timevar_pop (TV_PCH_CPP_RESTORE);
351 goto end;
353 timevar_pop (TV_PCH_CPP_RESTORE);
356 fclose (f);
358 line_table->trace_includes = saved_trace_includes;
359 linemap_add (line_table, LC_ENTER, 0, saved_loc.file, saved_loc.line);
361 /* Give the front end a chance to take action after a PCH file has
362 been loaded. */
363 if (lang_post_pch_load)
364 (*lang_post_pch_load) ();
366 end:
367 timevar_pop (TV_PCH_RESTORE);
370 /* Indicate that no more PCH files should be read. */
372 void
373 c_common_no_more_pch (void)
375 if (cpp_get_callbacks (parse_in)->valid_pch)
377 cpp_get_callbacks (parse_in)->valid_pch = NULL;
378 void *addr = NULL;
379 host_hooks.gt_pch_use_address (addr, 0, -1, 0);
383 /* Handle #pragma GCC pch_preprocess, to load in the PCH file. */
385 void
386 c_common_pch_pragma (cpp_reader *pfile, const char *name)
388 int fd;
390 if (!cpp_get_options (pfile)->preprocessed)
392 error ("%<pch_preprocess%> pragma should only be used "
393 "with %<-fpreprocessed%>");
394 inform (input_location, "use %<#include%> instead");
395 return;
398 fd = open (name, O_RDONLY | O_BINARY, 0666);
399 if (fd == -1)
400 fatal_error (input_location, "%s: couldn%'t open PCH file: %m", name);
402 if (c_common_valid_pch (pfile, name, fd) != 1)
404 if (!cpp_get_options (pfile)->warn_invalid_pch)
405 inform (input_location, "use %<-Winvalid-pch%> for more information");
406 fatal_error (input_location, "%s: PCH file was invalid", name);
409 c_common_read_pch (pfile, name, fd, name);
411 close (fd);