]>
Commit | Line | Data |
---|---|---|
17211ab5 | 1 | /* Part of CPP library. (Precompiled header reading/writing.) |
73e61092 | 2 | Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. |
17211ab5 GK |
3 | |
4 | This program is free software; you can redistribute it and/or modify it | |
5 | under the terms of the GNU General Public License as published by the | |
6 | Free Software Foundation; either version 2, or (at your option) any | |
7 | later version. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | GNU General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License | |
15 | along with this program; if not, write to the Free Software | |
16 | Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
17 | ||
18 | #include "config.h" | |
19 | #include "system.h" | |
17211ab5 | 20 | #include "cpplib.h" |
4f4e53dd | 21 | #include "internal.h" |
17211ab5 GK |
22 | #include "hashtab.h" |
23 | #include "mkdeps.h" | |
24 | ||
6cf87ca4 ZW |
25 | static int write_macdef (cpp_reader *, cpp_hashnode *, void *); |
26 | static int save_idents (cpp_reader *, cpp_hashnode *, void *); | |
27 | static hashval_t hashmem (const void *, size_t); | |
28 | static hashval_t cpp_string_hash (const void *); | |
29 | static int cpp_string_eq (const void *, const void *); | |
30 | static int count_defs (cpp_reader *, cpp_hashnode *, void *); | |
31 | static int comp_hashnodes (const void *, const void *); | |
32 | static int collect_ht_nodes (cpp_reader *, cpp_hashnode *, void *); | |
33 | static int write_defs (cpp_reader *, cpp_hashnode *, void *); | |
34 | static int save_macros (cpp_reader *, cpp_hashnode *, void *); | |
17211ab5 GK |
35 | |
36 | /* This structure represents a macro definition on disk. */ | |
37 | struct macrodef_struct | |
38 | { | |
39 | unsigned int definition_length; | |
40 | unsigned short name_length; | |
41 | unsigned short flags; | |
42 | }; | |
43 | ||
44 | /* This is how we write out a macro definition. | |
45 | Suitable for being called by cpp_forall_identifiers. */ | |
46 | ||
47 | static int | |
6cf87ca4 | 48 | write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) |
17211ab5 GK |
49 | { |
50 | FILE *f = (FILE *) file_p; | |
51 | switch (hn->type) | |
52 | { | |
53 | case NT_VOID: | |
54 | if (! (hn->flags & NODE_POISONED)) | |
55 | return 1; | |
56 | ||
57 | case NT_MACRO: | |
58 | if ((hn->flags & NODE_BUILTIN)) | |
59 | return 1; | |
60 | ||
61 | { | |
62 | struct macrodef_struct s; | |
63 | const unsigned char *defn; | |
64 | ||
65 | s.name_length = NODE_LEN (hn); | |
66 | s.flags = hn->flags & NODE_POISONED; | |
67 | ||
68 | if (hn->type == NT_MACRO) | |
69 | { | |
70 | defn = cpp_macro_definition (pfile, hn); | |
71 | s.definition_length = ustrlen (defn); | |
72 | } | |
73 | else | |
74 | { | |
75 | defn = NODE_NAME (hn); | |
76 | s.definition_length = s.name_length; | |
77 | } | |
78 | ||
79 | if (fwrite (&s, sizeof (s), 1, f) != 1 | |
80 | || fwrite (defn, 1, s.definition_length, f) != s.definition_length) | |
81 | { | |
0527bc4e JDA |
82 | cpp_errno (pfile, CPP_DL_ERROR, |
83 | "while writing precompiled header"); | |
17211ab5 GK |
84 | return 0; |
85 | } | |
86 | } | |
87 | return 1; | |
88 | ||
89 | case NT_ASSERTION: | |
90 | /* Not currently implemented. */ | |
91 | return 1; | |
92 | ||
93 | default: | |
94 | abort (); | |
95 | } | |
96 | } | |
97 | ||
98 | /* This structure records the names of the defined macros. | |
99 | It's also used as a callback structure for size_initial_idents | |
100 | and save_idents. */ | |
101 | ||
102 | struct cpp_savedstate | |
103 | { | |
104 | /* A hash table of the defined identifiers. */ | |
105 | htab_t definedhash; | |
106 | /* The size of the definitions of those identifiers (the size of | |
107 | 'definedstrs'). */ | |
108 | size_t hashsize; | |
c419b113 MA |
109 | /* Number of definitions */ |
110 | size_t n_defs; | |
71c0e7fc | 111 | /* Array of definitions. In cpp_write_pch_deps it is used for sorting. */ |
c419b113 | 112 | cpp_hashnode **defs; |
17211ab5 GK |
113 | /* Space for the next definition. Definitions are null-terminated |
114 | strings. */ | |
115 | unsigned char *definedstrs; | |
116 | }; | |
117 | ||
118 | /* Save this identifier into the state: put it in the hash table, | |
119 | put the definition in 'definedstrs'. */ | |
120 | ||
121 | static int | |
6cf87ca4 | 122 | save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) |
17211ab5 GK |
123 | { |
124 | struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; | |
125 | ||
126 | if (hn->type != NT_VOID) | |
127 | { | |
128 | struct cpp_string news; | |
129 | void **slot; | |
130 | ||
131 | news.len = NODE_LEN (hn); | |
132 | news.text= NODE_NAME (hn); | |
133 | slot = htab_find_slot (ss->definedhash, &news, INSERT); | |
134 | if (*slot == NULL) | |
135 | { | |
136 | struct cpp_string *sp; | |
137 | unsigned char *text; | |
138 | ||
139 | sp = xmalloc (sizeof (struct cpp_string)); | |
140 | *slot = sp; | |
141 | ||
142 | sp->len = NODE_LEN (hn); | |
143 | sp->text = text = xmalloc (NODE_LEN (hn)); | |
144 | memcpy (text, NODE_NAME (hn), NODE_LEN (hn)); | |
145 | } | |
146 | } | |
147 | ||
148 | return 1; | |
149 | } | |
150 | ||
151 | /* Hash some memory in a generic way. */ | |
152 | ||
153 | static hashval_t | |
6cf87ca4 | 154 | hashmem (const void *p_p, size_t sz) |
17211ab5 GK |
155 | { |
156 | const unsigned char *p = (const unsigned char *)p_p; | |
157 | size_t i; | |
158 | hashval_t h; | |
159 | ||
160 | h = 0; | |
161 | for (i = 0; i < sz; i++) | |
162 | h = h * 67 - (*p++ - 113); | |
163 | return h; | |
164 | } | |
165 | ||
166 | /* Hash a cpp string for the hashtable machinery. */ | |
167 | ||
168 | static hashval_t | |
6cf87ca4 | 169 | cpp_string_hash (const void *a_p) |
17211ab5 GK |
170 | { |
171 | const struct cpp_string *a = (const struct cpp_string *) a_p; | |
172 | return hashmem (a->text, a->len); | |
173 | } | |
174 | ||
175 | /* Compare two cpp strings for the hashtable machinery. */ | |
176 | ||
177 | static int | |
6cf87ca4 | 178 | cpp_string_eq (const void *a_p, const void *b_p) |
17211ab5 GK |
179 | { |
180 | const struct cpp_string *a = (const struct cpp_string *) a_p; | |
181 | const struct cpp_string *b = (const struct cpp_string *) b_p; | |
182 | return (a->len == b->len | |
183 | && memcmp (a->text, b->text, a->len) == 0); | |
184 | } | |
185 | ||
186 | /* Save the current definitions of the cpp_reader for dependency | |
187 | checking purposes. When writing a precompiled header, this should | |
188 | be called at the same point in the compilation as cpp_valid_state | |
189 | would be called when reading the precompiled header back in. */ | |
190 | ||
191 | int | |
6cf87ca4 | 192 | cpp_save_state (cpp_reader *r, FILE *f) |
17211ab5 GK |
193 | { |
194 | /* Save the list of non-void identifiers for the dependency checking. */ | |
195 | r->savedstate = xmalloc (sizeof (struct cpp_savedstate)); | |
196 | r->savedstate->definedhash = htab_create (100, cpp_string_hash, | |
197 | cpp_string_eq, NULL); | |
198 | cpp_forall_identifiers (r, save_idents, r->savedstate); | |
199 | ||
200 | /* Write out the list of defined identifiers. */ | |
201 | cpp_forall_identifiers (r, write_macdef, f); | |
202 | ||
203 | return 0; | |
204 | } | |
205 | ||
206 | /* Calculate the 'hashsize' field of the saved state. */ | |
207 | ||
208 | static int | |
6cf87ca4 | 209 | count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) |
17211ab5 GK |
210 | { |
211 | struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; | |
212 | ||
213 | switch (hn->type) | |
214 | { | |
215 | case NT_MACRO: | |
216 | if (hn->flags & NODE_BUILTIN) | |
217 | return 1; | |
218 | ||
219 | /* else fall through. */ | |
220 | ||
221 | case NT_VOID: | |
222 | { | |
223 | struct cpp_string news; | |
224 | void **slot; | |
225 | ||
226 | news.len = NODE_LEN (hn); | |
227 | news.text = NODE_NAME (hn); | |
228 | slot = htab_find (ss->definedhash, &news); | |
229 | if (slot == NULL) | |
c419b113 MA |
230 | { |
231 | ss->hashsize += NODE_LEN (hn) + 1; | |
232 | ss->n_defs += 1; | |
233 | } | |
17211ab5 GK |
234 | } |
235 | return 1; | |
236 | ||
237 | case NT_ASSERTION: | |
238 | /* Not currently implemented. */ | |
239 | return 1; | |
240 | ||
241 | default: | |
242 | abort (); | |
243 | } | |
244 | } | |
245 | ||
71c0e7fc | 246 | /* Collect the identifiers into the state's string table. */ |
17211ab5 | 247 | static int |
6cf87ca4 | 248 | write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) |
17211ab5 GK |
249 | { |
250 | struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; | |
251 | ||
252 | switch (hn->type) | |
253 | { | |
254 | case NT_MACRO: | |
255 | if (hn->flags & NODE_BUILTIN) | |
256 | return 1; | |
257 | ||
258 | /* else fall through. */ | |
259 | ||
260 | case NT_VOID: | |
261 | { | |
262 | struct cpp_string news; | |
263 | void **slot; | |
264 | ||
265 | news.len = NODE_LEN (hn); | |
266 | news.text = NODE_NAME (hn); | |
267 | slot = htab_find (ss->definedhash, &news); | |
268 | if (slot == NULL) | |
269 | { | |
c419b113 MA |
270 | ss->defs[ss->n_defs] = hn; |
271 | ss->n_defs += 1; | |
17211ab5 GK |
272 | } |
273 | } | |
274 | return 1; | |
275 | ||
276 | case NT_ASSERTION: | |
277 | /* Not currently implemented. */ | |
278 | return 1; | |
279 | ||
280 | default: | |
281 | abort (); | |
282 | } | |
283 | } | |
284 | ||
c419b113 MA |
285 | /* Comparison function for qsort. The arguments point to pointers of |
286 | type ht_hashnode *. */ | |
287 | static int | |
6cf87ca4 | 288 | comp_hashnodes (const void *px, const void *py) |
c419b113 MA |
289 | { |
290 | cpp_hashnode *x = *(cpp_hashnode **) px; | |
291 | cpp_hashnode *y = *(cpp_hashnode **) py; | |
292 | return ustrcmp (NODE_NAME (x), NODE_NAME (y)); | |
293 | } | |
294 | ||
17211ab5 GK |
295 | /* Write out the remainder of the dependency information. This should be |
296 | called after the PCH is ready to be saved. */ | |
297 | ||
298 | int | |
6cf87ca4 | 299 | cpp_write_pch_deps (cpp_reader *r, FILE *f) |
17211ab5 GK |
300 | { |
301 | struct macrodef_struct z; | |
302 | struct cpp_savedstate *const ss = r->savedstate; | |
303 | unsigned char *definedstrs; | |
c419b113 | 304 | size_t i; |
17211ab5 | 305 | |
c419b113 | 306 | /* Collect the list of identifiers which have been seen and |
17211ab5 | 307 | weren't defined to anything previously. */ |
c419b113 MA |
308 | ss->hashsize = 0; |
309 | ss->n_defs = 0; | |
17211ab5 | 310 | cpp_forall_identifiers (r, count_defs, ss); |
c419b113 MA |
311 | |
312 | ss->defs = xmalloc (ss->n_defs * sizeof (cpp_hashnode *)); | |
313 | ss->n_defs = 0; | |
17211ab5 | 314 | cpp_forall_identifiers (r, write_defs, ss); |
c419b113 | 315 | |
71c0e7fc | 316 | /* Sort the list, copy it into a buffer, and write it out. */ |
c419b113 MA |
317 | qsort (ss->defs, ss->n_defs, sizeof (cpp_hashnode *), &comp_hashnodes); |
318 | definedstrs = ss->definedstrs = xmalloc (ss->hashsize); | |
319 | for (i = 0; i < ss->n_defs; ++i) | |
320 | { | |
321 | size_t len = NODE_LEN (ss->defs[i]); | |
322 | memcpy (definedstrs, NODE_NAME (ss->defs[i]), len + 1); | |
323 | definedstrs += len + 1; | |
324 | } | |
325 | ||
17211ab5 GK |
326 | memset (&z, 0, sizeof (z)); |
327 | z.definition_length = ss->hashsize; | |
328 | if (fwrite (&z, sizeof (z), 1, f) != 1 | |
c419b113 | 329 | || fwrite (ss->definedstrs, ss->hashsize, 1, f) != 1) |
17211ab5 | 330 | { |
0527bc4e | 331 | cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); |
17211ab5 GK |
332 | return -1; |
333 | } | |
c419b113 | 334 | free (ss->definedstrs); |
17211ab5 GK |
335 | |
336 | /* Free the saved state. */ | |
337 | free (ss); | |
338 | r->savedstate = NULL; | |
339 | return 0; | |
340 | } | |
341 | ||
342 | /* Write out the definitions of the preprocessor, in a form suitable for | |
343 | cpp_read_state. */ | |
344 | ||
345 | int | |
6cf87ca4 | 346 | cpp_write_pch_state (cpp_reader *r, FILE *f) |
17211ab5 GK |
347 | { |
348 | struct macrodef_struct z; | |
349 | ||
17211ab5 GK |
350 | if (!r->deps) |
351 | r->deps = deps_init (); | |
352 | ||
353 | if (deps_save (r->deps, f) != 0) | |
354 | { | |
0527bc4e | 355 | cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); |
17211ab5 GK |
356 | return -1; |
357 | } | |
358 | ||
73e61092 GK |
359 | if (! _cpp_save_file_entries (r, f)) |
360 | { | |
361 | cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); | |
362 | return -1; | |
363 | } | |
364 | ||
17211ab5 GK |
365 | return 0; |
366 | } | |
367 | ||
c419b113 MA |
368 | |
369 | /* Data structure to transform hash table nodes into a sorted list */ | |
370 | ||
371 | struct ht_node_list | |
372 | { | |
373 | /* Array of nodes */ | |
374 | cpp_hashnode **defs; | |
375 | /* Number of nodes in the array */ | |
376 | size_t n_defs; | |
377 | /* Size of the allocated array */ | |
378 | size_t asize; | |
379 | }; | |
380 | ||
381 | /* Callback for collecting identifiers from hash table */ | |
382 | ||
383 | static int | |
6cf87ca4 ZW |
384 | collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, |
385 | void *nl_p) | |
c419b113 MA |
386 | { |
387 | struct ht_node_list *const nl = (struct ht_node_list *)nl_p; | |
388 | ||
389 | if (hn->type != NT_VOID || hn->flags & NODE_POISONED) | |
390 | { | |
391 | if (nl->n_defs == nl->asize) | |
392 | { | |
393 | nl->asize *= 2; | |
394 | nl->defs = xrealloc (nl->defs, nl->asize * sizeof (cpp_hashnode *)); | |
395 | } | |
396 | ||
397 | nl->defs[nl->n_defs] = hn; | |
398 | ++nl->n_defs; | |
399 | } | |
400 | return 1; | |
401 | } | |
402 | ||
403 | ||
17211ab5 GK |
404 | /* Return nonzero if FD is a precompiled header which is consistent |
405 | with the preprocessor's current definitions. It will be consistent | |
406 | when: | |
407 | ||
408 | - anything that was defined just before the PCH was generated | |
409 | is defined the same way now; and | |
410 | - anything that was not defined then, but is defined now, was not | |
411 | used by the PCH. | |
412 | ||
413 | NAME is used to print warnings if `warn_invalid_pch' is set in the | |
414 | reader's flags. | |
415 | */ | |
416 | ||
417 | int | |
6cf87ca4 | 418 | cpp_valid_state (cpp_reader *r, const char *name, int fd) |
17211ab5 GK |
419 | { |
420 | struct macrodef_struct m; | |
421 | size_t namebufsz = 256; | |
422 | unsigned char *namebuf = xmalloc (namebufsz); | |
423 | unsigned char *undeftab = NULL; | |
36801818 | 424 | struct ht_node_list nl = { 0, 0, 0 }; |
c419b113 | 425 | unsigned char *first, *last; |
17211ab5 GK |
426 | unsigned int i; |
427 | ||
428 | /* Read in the list of identifiers that must be defined | |
429 | Check that they are defined in the same way. */ | |
430 | for (;;) | |
431 | { | |
432 | cpp_hashnode *h; | |
433 | const unsigned char *newdefn; | |
434 | ||
435 | if (read (fd, &m, sizeof (m)) != sizeof (m)) | |
436 | goto error; | |
437 | ||
438 | if (m.name_length == 0) | |
439 | break; | |
440 | ||
c0d578e6 GK |
441 | /* If this file is already preprocessed, there won't be any |
442 | macros defined, and that's OK. */ | |
443 | if (CPP_OPTION (r, preprocessed)) | |
444 | { | |
445 | if (lseek (fd, m.definition_length, SEEK_CUR) == -1) | |
446 | goto error; | |
447 | continue; | |
448 | } | |
449 | ||
17211ab5 GK |
450 | if (m.definition_length > namebufsz) |
451 | { | |
452 | free (namebuf); | |
453 | namebufsz = m.definition_length + 256; | |
454 | namebuf = xmalloc (namebufsz); | |
455 | } | |
c0d578e6 | 456 | |
17211ab5 GK |
457 | if ((size_t)read (fd, namebuf, m.definition_length) |
458 | != m.definition_length) | |
459 | goto error; | |
460 | ||
461 | h = cpp_lookup (r, namebuf, m.name_length); | |
462 | if (m.flags & NODE_POISONED | |
463 | || h->type != NT_MACRO | |
464 | || h->flags & NODE_POISONED) | |
465 | { | |
466 | if (CPP_OPTION (r, warn_invalid_pch)) | |
0527bc4e | 467 | cpp_error (r, CPP_DL_WARNING_SYSHDR, |
17211ab5 GK |
468 | "%s: not used because `%.*s' not defined", |
469 | name, m.name_length, namebuf); | |
470 | goto fail; | |
471 | } | |
472 | ||
473 | newdefn = cpp_macro_definition (r, h); | |
474 | ||
475 | if (m.definition_length != ustrlen (newdefn) | |
476 | || memcmp (namebuf, newdefn, m.definition_length) != 0) | |
477 | { | |
478 | if (CPP_OPTION (r, warn_invalid_pch)) | |
0527bc4e | 479 | cpp_error (r, CPP_DL_WARNING_SYSHDR, |
17211ab5 GK |
480 | "%s: not used because `%.*s' defined as `%s' not `%.*s'", |
481 | name, m.name_length, namebuf, newdefn + m.name_length, | |
482 | m.definition_length - m.name_length, | |
483 | namebuf + m.name_length); | |
484 | goto fail; | |
485 | } | |
486 | } | |
487 | free (namebuf); | |
488 | namebuf = NULL; | |
489 | ||
490 | /* Read in the list of identifiers that must not be defined. | |
491 | Check that they really aren't. */ | |
492 | undeftab = xmalloc (m.definition_length); | |
493 | if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length) | |
494 | goto error; | |
c419b113 MA |
495 | |
496 | /* Collect identifiers from the current hash table. */ | |
497 | nl.n_defs = 0; | |
498 | nl.asize = 10; | |
499 | nl.defs = xmalloc (nl.asize * sizeof (cpp_hashnode *)); | |
500 | cpp_forall_identifiers (r, &collect_ht_nodes, &nl); | |
501 | qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes); | |
502 | ||
503 | /* Loop through nl.defs and undeftab, both of which are sorted lists. | |
71c0e7fc | 504 | There should be no matches. */ |
c419b113 MA |
505 | first = undeftab; |
506 | last = undeftab + m.definition_length; | |
507 | i = 0; | |
508 | ||
509 | while (first < last && i < nl.n_defs) | |
17211ab5 | 510 | { |
c419b113 MA |
511 | int cmp = ustrcmp (first, NODE_NAME (nl.defs[i])); |
512 | ||
513 | if (cmp < 0) | |
514 | first += ustrlen (first) + 1; | |
515 | else if (cmp > 0) | |
516 | ++i; | |
517 | else | |
ccc01444 GK |
518 | { |
519 | if (CPP_OPTION (r, warn_invalid_pch)) | |
0527bc4e | 520 | cpp_error (r, CPP_DL_WARNING_SYSHDR, |
ccc01444 GK |
521 | "%s: not used because `%s' is defined", |
522 | name, first); | |
523 | goto fail; | |
524 | } | |
17211ab5 | 525 | } |
c419b113 MA |
526 | |
527 | free(nl.defs); | |
17211ab5 GK |
528 | free (undeftab); |
529 | ||
530 | /* We win! */ | |
531 | return 0; | |
532 | ||
533 | error: | |
0527bc4e | 534 | cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header"); |
17211ab5 GK |
535 | return -1; |
536 | ||
537 | fail: | |
538 | if (namebuf != NULL) | |
539 | free (namebuf); | |
540 | if (undeftab != NULL) | |
541 | free (undeftab); | |
c419b113 MA |
542 | if (nl.defs != NULL) |
543 | free (nl.defs); | |
17211ab5 GK |
544 | return 1; |
545 | } | |
546 | ||
d8044160 | 547 | /* Save all the existing macros. */ |
17211ab5 GK |
548 | |
549 | struct save_macro_data | |
550 | { | |
d8044160 | 551 | uchar **defns; |
17211ab5 | 552 | size_t count; |
d8044160 | 553 | size_t array_size; |
17211ab5 GK |
554 | char **saved_pragmas; |
555 | }; | |
556 | ||
d8044160 GK |
557 | /* Save the definition of a single macro, so that it will persist |
558 | across a PCH restore. Because macro data is in GCed memory, which | |
559 | will be blown away by PCH, it must be temporarily copied to | |
560 | malloced memory. (The macros will refer to identifier nodes which | |
561 | are also GCed and so on, so the copying is done by turning them | |
562 | into self-contained strings.) The assumption is that most macro | |
563 | definitions will come from the PCH file, not from the compilation | |
564 | before the PCH file is loaded, so it doesn't matter that this is | |
565 | a little expensive. | |
566 | ||
567 | It would reduce the cost even further if macros defined in the PCH | |
568 | file were not saved in this way, but this is not done (yet), except | |
569 | for builtins, and for #assert by default. */ | |
17211ab5 GK |
570 | |
571 | static int | |
d8044160 | 572 | save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) |
17211ab5 GK |
573 | { |
574 | struct save_macro_data *data = (struct save_macro_data *)data_p; | |
575 | if (h->type != NT_VOID | |
576 | && (h->flags & NODE_BUILTIN) == 0) | |
577 | { | |
d8044160 GK |
578 | if (data->count == data->array_size) |
579 | { | |
580 | data->array_size *= 2; | |
581 | data->defns = xrealloc (data->defns, (data->array_size | |
582 | * sizeof (uchar *))); | |
583 | } | |
584 | ||
585 | switch (h->type) | |
17211ab5 | 586 | { |
d8044160 GK |
587 | case NT_ASSERTION: |
588 | /* Not currently implemented. */ | |
589 | return 1; | |
590 | ||
591 | case NT_MACRO: | |
592 | { | |
593 | const uchar * defn = cpp_macro_definition (r, h); | |
594 | size_t defnlen = ustrlen (defn); | |
595 | ||
596 | data->defns[data->count] = xmemdup (defn, defnlen, defnlen + 2); | |
597 | data->defns[data->count][defnlen] = '\n'; | |
598 | } | |
599 | break; | |
600 | ||
601 | default: | |
602 | abort (); | |
17211ab5 | 603 | } |
17211ab5 | 604 | data->count++; |
17211ab5 GK |
605 | } |
606 | return 1; | |
607 | } | |
608 | ||
609 | /* Prepare to restore the state, by saving the currently-defined | |
610 | macros in 'data'. */ | |
611 | ||
612 | void | |
6cf87ca4 | 613 | cpp_prepare_state (cpp_reader *r, struct save_macro_data **data) |
17211ab5 GK |
614 | { |
615 | struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data)); | |
616 | ||
d8044160 GK |
617 | d->array_size = 512; |
618 | d->defns = xmalloc (d->array_size * sizeof (d->defns[0])); | |
619 | d->count = 0; | |
17211ab5 GK |
620 | cpp_forall_identifiers (r, save_macros, d); |
621 | d->saved_pragmas = _cpp_save_pragma_names (r); | |
622 | *data = d; | |
623 | } | |
624 | ||
17211ab5 GK |
625 | /* Given a precompiled header that was previously determined to be valid, |
626 | apply all its definitions (and undefinitions) to the current state. | |
627 | DEPNAME is passed to deps_restore. */ | |
628 | ||
629 | int | |
6cf87ca4 ZW |
630 | cpp_read_state (cpp_reader *r, const char *name, FILE *f, |
631 | struct save_macro_data *data) | |
17211ab5 GK |
632 | { |
633 | struct macrodef_struct m; | |
17211ab5 GK |
634 | struct save_macro_item *d; |
635 | size_t i, mac_count; | |
d8044160 | 636 | struct lexer_state old_state; |
17211ab5 | 637 | |
17211ab5 GK |
638 | /* Restore spec_nodes, which will be full of references to the old |
639 | hashtable entries and so will now be invalid. */ | |
640 | { | |
641 | struct spec_nodes *s = &r->spec_nodes; | |
642 | s->n_defined = cpp_lookup (r, DSC("defined")); | |
643 | s->n_true = cpp_lookup (r, DSC("true")); | |
644 | s->n_false = cpp_lookup (r, DSC("false")); | |
645 | s->n__VA_ARGS__ = cpp_lookup (r, DSC("__VA_ARGS__")); | |
646 | } | |
647 | ||
17211ab5 | 648 | old_state = r->state; |
17211ab5 GK |
649 | r->state.in_directive = 1; |
650 | r->state.prevent_expansion = 1; | |
651 | r->state.angled_headers = 0; | |
652 | ||
d8044160 GK |
653 | /* Run through the carefully-saved macros, insert them. */ |
654 | for (i = 0; i < data->count; i++) | |
17211ab5 GK |
655 | { |
656 | cpp_hashnode *h; | |
d8044160 GK |
657 | size_t namelen; |
658 | uchar *defn; | |
17211ab5 | 659 | |
d8044160 GK |
660 | namelen = strcspn (data->defns[i], "( \n"); |
661 | h = cpp_lookup (r, data->defns[i], namelen); | |
662 | defn = data->defns[i] + namelen; | |
17211ab5 | 663 | |
d8044160 GK |
664 | /* The PCH file is valid, so we know that if there is a definition |
665 | from the PCH file it must be the same as the one we had | |
666 | originally, and so do not need to restore it. */ | |
667 | if (h->type == NT_VOID) | |
17211ab5 | 668 | { |
d8044160 | 669 | if (cpp_push_buffer (r, defn, ustrchr (defn, '\n') - defn, true) |
40de9f76 | 670 | != NULL) |
17211ab5 | 671 | { |
26aea073 | 672 | _cpp_clean_line (r); |
17211ab5 GK |
673 | if (!_cpp_create_definition (r, h)) |
674 | abort (); | |
675 | _cpp_pop_buffer (r); | |
676 | } | |
677 | else | |
678 | abort (); | |
679 | } | |
17211ab5 | 680 | |
d8044160 GK |
681 | free (data->defns[i]); |
682 | } | |
17211ab5 | 683 | r->state = old_state; |
d8044160 GK |
684 | |
685 | _cpp_restore_pragma_names (r, data->saved_pragmas); | |
686 | ||
687 | free (data); | |
17211ab5 GK |
688 | |
689 | if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL) | |
690 | != 0) | |
691 | goto error; | |
692 | ||
73e61092 GK |
693 | if (! _cpp_read_file_entries (r, f)) |
694 | goto error; | |
695 | ||
17211ab5 GK |
696 | return 0; |
697 | ||
698 | error: | |
0527bc4e | 699 | cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header"); |
17211ab5 GK |
700 | return -1; |
701 | } |