Mercurial > hg > CbC > CbC_gcc
annotate libcpp/pch.c @ 158:494b0b89df80 default tip
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:13:55 +0900 |
parents | 1830386684a0 |
children |
rev | line source |
---|---|
0 | 1 /* Part of CPP library. (Precompiled header reading/writing.) |
145 | 2 Copyright (C) 2000-2020 Free Software Foundation, Inc. |
0 | 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 3, 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; see the file COPYING3. If not see | |
16 <http://www.gnu.org/licenses/>. */ | |
17 | |
18 #include "config.h" | |
19 #include "system.h" | |
20 #include "cpplib.h" | |
21 #include "internal.h" | |
22 #include "hashtab.h" | |
23 #include "mkdeps.h" | |
24 | |
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 *); | |
47
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
35 static int _cpp_save_pushed_macros (cpp_reader *, FILE *); |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
36 static int _cpp_restore_pushed_macros (cpp_reader *, FILE *); |
0 | 37 |
38 /* This structure represents a macro definition on disk. */ | |
39 struct macrodef_struct | |
40 { | |
41 unsigned int definition_length; | |
42 unsigned short name_length; | |
43 unsigned short flags; | |
44 }; | |
45 | |
46 /* This is how we write out a macro definition. | |
47 Suitable for being called by cpp_forall_identifiers. */ | |
48 | |
49 static int | |
50 write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) | |
51 { | |
52 FILE *f = (FILE *) file_p; | |
131 | 53 bool is_void = false; |
0 | 54 switch (hn->type) |
55 { | |
56 case NT_VOID: | |
57 if (! (hn->flags & NODE_POISONED)) | |
58 return 1; | |
131 | 59 is_void = true; |
60 goto poisoned; | |
0 | 61 |
131 | 62 case NT_BUILTIN_MACRO: |
0 | 63 return 1; |
64 | |
131 | 65 case NT_USER_MACRO: |
66 if (hn->value.macro->kind != cmk_assert) | |
67 { | |
68 poisoned: | |
69 struct macrodef_struct s; | |
70 const unsigned char *defn; | |
71 | |
72 s.name_length = NODE_LEN (hn); | |
73 s.flags = hn->flags & NODE_POISONED; | |
74 | |
75 if (is_void) | |
76 { | |
77 defn = NODE_NAME (hn); | |
78 s.definition_length = s.name_length; | |
79 } | |
80 else | |
81 { | |
82 defn = cpp_macro_definition (pfile, hn); | |
83 s.definition_length = ustrlen (defn); | |
84 } | |
85 | |
86 if (fwrite (&s, sizeof (s), 1, f) != 1 | |
87 || fwrite (defn, 1, s.definition_length, f) != s.definition_length) | |
88 { | |
89 cpp_errno (pfile, CPP_DL_ERROR, | |
90 "while writing precompiled header"); | |
91 return 0; | |
92 } | |
93 } | |
0 | 94 return 1; |
95 | |
96 default: | |
97 abort (); | |
98 } | |
99 } | |
100 | |
101 /* This structure records the names of the defined macros. | |
102 It's also used as a callback structure for size_initial_idents | |
103 and save_idents. */ | |
104 | |
105 struct cpp_savedstate | |
106 { | |
107 /* A hash table of the defined identifiers. */ | |
108 htab_t definedhash; | |
109 /* The size of the definitions of those identifiers (the size of | |
110 'definedstrs'). */ | |
111 size_t hashsize; | |
112 /* Number of definitions */ | |
113 size_t n_defs; | |
114 /* Array of definitions. In cpp_write_pch_deps it is used for sorting. */ | |
115 cpp_hashnode **defs; | |
116 /* Space for the next definition. Definitions are null-terminated | |
117 strings. */ | |
118 unsigned char *definedstrs; | |
119 }; | |
120 | |
121 /* Save this identifier into the state: put it in the hash table, | |
122 put the definition in 'definedstrs'. */ | |
123 | |
124 static int | |
125 save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) | |
126 { | |
127 struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; | |
128 | |
129 if (hn->type != NT_VOID) | |
130 { | |
131 struct cpp_string news; | |
132 void **slot; | |
133 | |
134 news.len = NODE_LEN (hn); | |
135 news.text= NODE_NAME (hn); | |
136 slot = htab_find_slot (ss->definedhash, &news, INSERT); | |
137 if (*slot == NULL) | |
138 { | |
139 struct cpp_string *sp; | |
140 unsigned char *text; | |
141 | |
142 sp = XNEW (struct cpp_string); | |
143 *slot = sp; | |
144 | |
145 sp->len = NODE_LEN (hn); | |
146 sp->text = text = XNEWVEC (unsigned char, NODE_LEN (hn)); | |
147 memcpy (text, NODE_NAME (hn), NODE_LEN (hn)); | |
148 } | |
149 } | |
150 | |
151 return 1; | |
152 } | |
153 | |
154 /* Hash some memory in a generic way. */ | |
155 | |
156 static hashval_t | |
157 hashmem (const void *p_p, size_t sz) | |
158 { | |
159 const unsigned char *p = (const unsigned char *)p_p; | |
160 size_t i; | |
161 hashval_t h; | |
162 | |
163 h = 0; | |
164 for (i = 0; i < sz; i++) | |
165 h = h * 67 - (*p++ - 113); | |
166 return h; | |
167 } | |
168 | |
169 /* Hash a cpp string for the hashtable machinery. */ | |
170 | |
171 static hashval_t | |
172 cpp_string_hash (const void *a_p) | |
173 { | |
174 const struct cpp_string *a = (const struct cpp_string *) a_p; | |
175 return hashmem (a->text, a->len); | |
176 } | |
177 | |
178 /* Compare two cpp strings for the hashtable machinery. */ | |
179 | |
180 static int | |
181 cpp_string_eq (const void *a_p, const void *b_p) | |
182 { | |
183 const struct cpp_string *a = (const struct cpp_string *) a_p; | |
184 const struct cpp_string *b = (const struct cpp_string *) b_p; | |
185 return (a->len == b->len | |
186 && memcmp (a->text, b->text, a->len) == 0); | |
187 } | |
188 | |
111 | 189 /* Free memory associated with cpp_string. */ |
190 | |
191 static void | |
192 cpp_string_free (void *a_p) | |
193 { | |
194 struct cpp_string *a = (struct cpp_string *) a_p; | |
195 free ((void *) a->text); | |
196 free (a); | |
197 } | |
198 | |
0 | 199 /* Save the current definitions of the cpp_reader for dependency |
200 checking purposes. When writing a precompiled header, this should | |
201 be called at the same point in the compilation as cpp_valid_state | |
202 would be called when reading the precompiled header back in. */ | |
203 | |
204 int | |
205 cpp_save_state (cpp_reader *r, FILE *f) | |
206 { | |
207 /* Save the list of non-void identifiers for the dependency checking. */ | |
208 r->savedstate = XNEW (struct cpp_savedstate); | |
209 r->savedstate->definedhash = htab_create (100, cpp_string_hash, | |
111 | 210 cpp_string_eq, cpp_string_free); |
0 | 211 cpp_forall_identifiers (r, save_idents, r->savedstate); |
212 | |
213 /* Write out the list of defined identifiers. */ | |
214 cpp_forall_identifiers (r, write_macdef, f); | |
215 | |
216 return 0; | |
217 } | |
218 | |
219 /* Calculate the 'hashsize' field of the saved state. */ | |
220 | |
221 static int | |
222 count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) | |
223 { | |
224 struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; | |
225 | |
226 switch (hn->type) | |
227 { | |
131 | 228 case NT_BUILTIN_MACRO: |
229 return 1; | |
230 | |
231 case NT_USER_MACRO: | |
232 if (hn->value.macro->kind == cmk_assert) | |
0 | 233 return 1; |
234 | |
111 | 235 /* fall through. */ |
0 | 236 |
237 case NT_VOID: | |
238 { | |
239 struct cpp_string news; | |
240 void **slot; | |
241 | |
242 news.len = NODE_LEN (hn); | |
243 news.text = NODE_NAME (hn); | |
244 slot = (void **) htab_find (ss->definedhash, &news); | |
245 if (slot == NULL) | |
246 { | |
247 ss->hashsize += NODE_LEN (hn) + 1; | |
248 ss->n_defs += 1; | |
249 } | |
250 } | |
251 return 1; | |
252 | |
253 default: | |
254 abort (); | |
255 } | |
256 } | |
257 | |
258 /* Collect the identifiers into the state's string table. */ | |
259 static int | |
260 write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) | |
261 { | |
262 struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; | |
263 | |
264 switch (hn->type) | |
265 { | |
131 | 266 case NT_BUILTIN_MACRO: |
267 return 1; | |
268 | |
269 case NT_USER_MACRO: | |
270 if (hn->value.macro->kind == cmk_assert) | |
0 | 271 return 1; |
272 | |
111 | 273 /* fall through. */ |
0 | 274 |
275 case NT_VOID: | |
276 { | |
277 struct cpp_string news; | |
278 void **slot; | |
279 | |
280 news.len = NODE_LEN (hn); | |
281 news.text = NODE_NAME (hn); | |
282 slot = (void **) htab_find (ss->definedhash, &news); | |
283 if (slot == NULL) | |
284 { | |
285 ss->defs[ss->n_defs] = hn; | |
286 ss->n_defs += 1; | |
287 } | |
288 } | |
289 return 1; | |
290 | |
291 default: | |
292 abort (); | |
293 } | |
294 } | |
295 | |
296 /* Comparison function for qsort. The arguments point to pointers of | |
297 type ht_hashnode *. */ | |
298 static int | |
299 comp_hashnodes (const void *px, const void *py) | |
300 { | |
301 cpp_hashnode *x = *(cpp_hashnode **) px; | |
302 cpp_hashnode *y = *(cpp_hashnode **) py; | |
303 return ustrcmp (NODE_NAME (x), NODE_NAME (y)); | |
304 } | |
305 | |
306 /* Write out the remainder of the dependency information. This should be | |
307 called after the PCH is ready to be saved. */ | |
308 | |
309 int | |
310 cpp_write_pch_deps (cpp_reader *r, FILE *f) | |
311 { | |
312 struct macrodef_struct z; | |
313 struct cpp_savedstate *const ss = r->savedstate; | |
314 unsigned char *definedstrs; | |
315 size_t i; | |
316 | |
317 /* Collect the list of identifiers which have been seen and | |
318 weren't defined to anything previously. */ | |
319 ss->hashsize = 0; | |
320 ss->n_defs = 0; | |
321 cpp_forall_identifiers (r, count_defs, ss); | |
322 | |
323 ss->defs = XNEWVEC (cpp_hashnode *, ss->n_defs); | |
324 ss->n_defs = 0; | |
325 cpp_forall_identifiers (r, write_defs, ss); | |
326 | |
327 /* Sort the list, copy it into a buffer, and write it out. */ | |
328 qsort (ss->defs, ss->n_defs, sizeof (cpp_hashnode *), &comp_hashnodes); | |
329 definedstrs = ss->definedstrs = XNEWVEC (unsigned char, ss->hashsize); | |
330 for (i = 0; i < ss->n_defs; ++i) | |
331 { | |
332 size_t len = NODE_LEN (ss->defs[i]); | |
333 memcpy (definedstrs, NODE_NAME (ss->defs[i]), len + 1); | |
334 definedstrs += len + 1; | |
335 } | |
336 | |
337 memset (&z, 0, sizeof (z)); | |
338 z.definition_length = ss->hashsize; | |
339 if (fwrite (&z, sizeof (z), 1, f) != 1 | |
340 || fwrite (ss->definedstrs, ss->hashsize, 1, f) != 1) | |
341 { | |
342 cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); | |
343 return -1; | |
344 } | |
345 free (ss->definedstrs); | |
111 | 346 free (ss->defs); |
347 htab_delete (ss->definedhash); | |
0 | 348 |
349 /* Free the saved state. */ | |
350 free (ss); | |
351 r->savedstate = NULL; | |
352 | |
353 /* Save the next value of __COUNTER__. */ | |
354 if (fwrite (&r->counter, sizeof (r->counter), 1, f) != 1) | |
355 { | |
356 cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); | |
357 return -1; | |
358 } | |
359 | |
360 return 0; | |
361 } | |
362 | |
363 /* Write out the definitions of the preprocessor, in a form suitable for | |
364 cpp_read_state. */ | |
365 | |
366 int | |
367 cpp_write_pch_state (cpp_reader *r, FILE *f) | |
368 { | |
369 if (!r->deps) | |
370 r->deps = deps_init (); | |
371 | |
372 if (deps_save (r->deps, f) != 0) | |
373 { | |
374 cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); | |
375 return -1; | |
376 } | |
377 | |
378 if (! _cpp_save_file_entries (r, f)) | |
379 { | |
380 cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); | |
381 return -1; | |
382 } | |
383 | |
384 /* Save the next __COUNTER__ value. When we include a precompiled header, | |
385 we need to start at the offset we would have if the header had been | |
386 included normally. */ | |
387 if (fwrite (&r->counter, sizeof (r->counter), 1, f) != 1) | |
388 { | |
389 cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); | |
390 return -1; | |
391 } | |
392 | |
47
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
393 /* Write saved macros. */ |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
394 if (! _cpp_save_pushed_macros (r, f)) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
395 { |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
396 cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
397 return -1; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
398 } |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
399 |
0 | 400 return 0; |
401 } | |
402 | |
47
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
403 static int |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
404 _cpp_restore_pushed_macros (cpp_reader *r, FILE *f) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
405 { |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
406 size_t count_saved = 0; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
407 size_t i; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
408 struct def_pragma_macro *p; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
409 size_t nlen; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
410 uchar *defn; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
411 size_t defnlen; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
412 |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
413 if (fread (&count_saved, sizeof (count_saved), 1, f) != 1) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
414 return 0; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
415 if (! count_saved) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
416 return 1; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
417 for (i = 0; i < count_saved; i++) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
418 { |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
419 if (fread (&nlen, sizeof (nlen), 1, f) != 1) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
420 return 0; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
421 p = XNEW (struct def_pragma_macro); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
422 memset (p, 0, sizeof (struct def_pragma_macro)); |
47
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
423 p->name = XNEWVAR (char, nlen + 1); |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
424 p->name[nlen] = 0; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
425 if (fread (p->name, nlen, 1, f) != 1) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
426 return 0; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
427 if (fread (&defnlen, sizeof (defnlen), 1, f) != 1) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
428 return 0; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
429 if (defnlen == 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
430 p->is_undef = 1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
431 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
432 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
433 defn = XNEWVEC (uchar, defnlen + 1); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
434 defn[defnlen] = 0; |
47
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
435 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
436 if (fread (defn, defnlen, 1, f) != 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
437 return 0; |
47
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
438 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
439 p->definition = defn; |
145 | 440 if (fread (&(p->line), sizeof (location_t), 1, f) != 1) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
441 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
442 defnlen = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
443 if (fread (&defnlen, sizeof (defnlen), 1, f) != 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
444 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
445 p->syshdr = ((defnlen & 1) != 0 ? 1 : 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
446 p->used = ((defnlen & 2) != 0 ? 1 : 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
447 } |
47
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
448 |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
449 p->next = r->pushed_macros; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
450 r->pushed_macros = p; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
451 } |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
452 return 1; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
453 } |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
454 |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
455 static int |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
456 _cpp_save_pushed_macros (cpp_reader *r, FILE *f) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
457 { |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
458 size_t count_saved = 0; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
459 size_t i; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
460 struct def_pragma_macro *p,**pp; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
461 size_t defnlen; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
462 |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
463 /* Get count. */ |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
464 p = r->pushed_macros; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
465 while (p != NULL) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
466 { |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
467 count_saved++; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
468 p = p->next; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
469 } |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
470 if (fwrite (&count_saved, sizeof (count_saved), 1, f) != 1) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
471 return 0; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
472 if (!count_saved) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
473 return 1; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
474 |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
475 pp = (struct def_pragma_macro **) alloca (sizeof (struct def_pragma_macro *) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
476 * count_saved); |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
477 /* Store them in reverse order. */ |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
478 p = r->pushed_macros; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
479 i = count_saved; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
480 while (p != NULL) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
481 { |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
482 --i; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
483 pp[i] = p; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
484 p = p->next; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
485 } |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
486 for (i = 0; i < count_saved; i++) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
487 { |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
488 defnlen = strlen (pp[i]->name); |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
489 if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1 |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
490 || fwrite (pp[i]->name, defnlen, 1, f) != 1) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
491 return 0; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
492 if (pp[i]->is_undef) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
493 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
494 defnlen = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
495 if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
496 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
497 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
498 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
499 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
500 defnlen = ustrlen (pp[i]->definition); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
501 if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
502 || fwrite (pp[i]->definition, defnlen, 1, f) != 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
503 return 0; |
145 | 504 if (fwrite (&(pp[i]->line), sizeof (location_t), 1, f) != 1) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
505 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
506 defnlen = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
507 defnlen |= (pp[i]->syshdr != 0 ? 1 : 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
508 defnlen |= (pp[i]->used != 0 ? 2 : 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
509 if (fwrite (&defnlen, sizeof (defnlen), 1, f) != 1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
510 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
511 } |
47
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
512 } |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
513 return 1; |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
514 } |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
515 |
0 | 516 |
517 /* Data structure to transform hash table nodes into a sorted list */ | |
518 | |
519 struct ht_node_list | |
520 { | |
521 /* Array of nodes */ | |
522 cpp_hashnode **defs; | |
523 /* Number of nodes in the array */ | |
524 size_t n_defs; | |
525 /* Size of the allocated array */ | |
526 size_t asize; | |
527 }; | |
528 | |
529 /* Callback for collecting identifiers from hash table */ | |
530 | |
531 static int | |
532 collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, | |
533 void *nl_p) | |
534 { | |
535 struct ht_node_list *const nl = (struct ht_node_list *)nl_p; | |
536 | |
537 if (hn->type != NT_VOID || hn->flags & NODE_POISONED) | |
538 { | |
539 if (nl->n_defs == nl->asize) | |
540 { | |
541 nl->asize *= 2; | |
542 nl->defs = XRESIZEVEC (cpp_hashnode *, nl->defs, nl->asize); | |
543 } | |
544 | |
545 nl->defs[nl->n_defs] = hn; | |
546 ++nl->n_defs; | |
547 } | |
548 return 1; | |
549 } | |
550 | |
551 | |
552 /* Return nonzero if FD is a precompiled header which is consistent | |
553 with the preprocessor's current definitions. It will be consistent | |
554 when: | |
555 | |
556 - anything that was defined just before the PCH was generated | |
557 is defined the same way now; and | |
558 - anything that was not defined then, but is defined now, was not | |
559 used by the PCH. | |
560 | |
561 NAME is used to print warnings if `warn_invalid_pch' is set in the | |
562 reader's flags. | |
563 */ | |
564 | |
565 int | |
566 cpp_valid_state (cpp_reader *r, const char *name, int fd) | |
567 { | |
568 struct macrodef_struct m; | |
569 size_t namebufsz = 256; | |
570 unsigned char *namebuf = XNEWVEC (unsigned char, namebufsz); | |
571 unsigned char *undeftab = NULL; | |
572 struct ht_node_list nl = { 0, 0, 0 }; | |
573 unsigned char *first, *last; | |
574 unsigned int i; | |
575 unsigned int counter; | |
576 | |
577 /* Read in the list of identifiers that must be defined | |
578 Check that they are defined in the same way. */ | |
579 for (;;) | |
580 { | |
581 cpp_hashnode *h; | |
582 const unsigned char *newdefn; | |
583 | |
584 if (read (fd, &m, sizeof (m)) != sizeof (m)) | |
585 goto error; | |
586 | |
587 if (m.name_length == 0) | |
588 break; | |
589 | |
590 /* If this file is already preprocessed, there won't be any | |
591 macros defined, and that's OK. */ | |
592 if (CPP_OPTION (r, preprocessed)) | |
593 { | |
594 if (lseek (fd, m.definition_length, SEEK_CUR) == -1) | |
595 goto error; | |
596 continue; | |
597 } | |
598 | |
599 if (m.definition_length > namebufsz) | |
600 { | |
601 free (namebuf); | |
602 namebufsz = m.definition_length + 256; | |
603 namebuf = XNEWVEC (unsigned char, namebufsz); | |
604 } | |
605 | |
606 if ((size_t)read (fd, namebuf, m.definition_length) | |
607 != m.definition_length) | |
608 goto error; | |
609 | |
610 h = cpp_lookup (r, namebuf, m.name_length); | |
611 if (m.flags & NODE_POISONED | |
612 || h->flags & NODE_POISONED) | |
613 { | |
614 if (CPP_OPTION (r, warn_invalid_pch)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
615 cpp_warning_syshdr (r, CPP_W_INVALID_PCH, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
616 "%s: not used because `%.*s' is poisoned", |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
617 name, m.name_length, namebuf); |
0 | 618 goto fail; |
619 } | |
620 | |
131 | 621 if (h->type == NT_VOID) |
0 | 622 { |
623 /* It's ok if __GCC_HAVE_DWARF2_CFI_ASM becomes undefined, | |
624 as in, when the PCH file is created with -g and we're | |
625 attempting to use it without -g. Restoring the PCH file | |
626 is supposed to bring in this definition *and* enable the | |
627 generation of call frame information, so that precompiled | |
111 | 628 definitions that take this macro into account, to decide |
0 | 629 what asm to emit, won't issue .cfi directives when the |
630 compiler doesn't. */ | |
631 if (!(h->flags & NODE_USED) | |
632 && m.name_length == sizeof ("__GCC_HAVE_DWARF2_CFI_ASM") - 1 | |
633 && !memcmp (namebuf, "__GCC_HAVE_DWARF2_CFI_ASM", m.name_length)) | |
634 continue; | |
635 | |
636 if (CPP_OPTION (r, warn_invalid_pch)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
637 cpp_warning_syshdr (r, CPP_W_INVALID_PCH, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
638 "%s: not used because `%.*s' not defined", |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
639 name, m.name_length, namebuf); |
0 | 640 goto fail; |
641 } | |
642 | |
643 newdefn = cpp_macro_definition (r, h); | |
644 | |
645 if (m.definition_length != ustrlen (newdefn) | |
646 || memcmp (namebuf, newdefn, m.definition_length) != 0) | |
647 { | |
648 if (CPP_OPTION (r, warn_invalid_pch)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
649 cpp_warning_syshdr (r, CPP_W_INVALID_PCH, |
0 | 650 "%s: not used because `%.*s' defined as `%s' not `%.*s'", |
651 name, m.name_length, namebuf, newdefn + m.name_length, | |
652 m.definition_length - m.name_length, | |
653 namebuf + m.name_length); | |
654 goto fail; | |
655 } | |
656 } | |
657 free (namebuf); | |
658 namebuf = NULL; | |
659 | |
660 /* Read in the list of identifiers that must not be defined. | |
661 Check that they really aren't. */ | |
662 undeftab = XNEWVEC (unsigned char, m.definition_length); | |
663 if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length) | |
664 goto error; | |
665 | |
666 /* Collect identifiers from the current hash table. */ | |
667 nl.n_defs = 0; | |
668 nl.asize = 10; | |
669 nl.defs = XNEWVEC (cpp_hashnode *, nl.asize); | |
670 cpp_forall_identifiers (r, &collect_ht_nodes, &nl); | |
671 qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes); | |
672 | |
673 /* Loop through nl.defs and undeftab, both of which are sorted lists. | |
674 There should be no matches. */ | |
675 first = undeftab; | |
676 last = undeftab + m.definition_length; | |
677 i = 0; | |
678 | |
679 while (first < last && i < nl.n_defs) | |
680 { | |
681 int cmp = ustrcmp (first, NODE_NAME (nl.defs[i])); | |
682 | |
683 if (cmp < 0) | |
684 first += ustrlen (first) + 1; | |
685 else if (cmp > 0) | |
686 ++i; | |
687 else | |
688 { | |
689 if (CPP_OPTION (r, warn_invalid_pch)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
690 cpp_warning_syshdr (r, CPP_W_INVALID_PCH, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
691 "%s: not used because `%s' is defined", |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
692 name, first); |
0 | 693 goto fail; |
694 } | |
695 } | |
696 | |
697 free(nl.defs); | |
698 nl.defs = NULL; | |
699 free (undeftab); | |
700 undeftab = NULL; | |
701 | |
702 /* Read in the next value of __COUNTER__. | |
703 Check that (a) __COUNTER__ was not used in the pch or (b) __COUNTER__ | |
704 has not been used in this translation unit. */ | |
705 if (read (fd, &counter, sizeof (counter)) != sizeof (counter)) | |
706 goto error; | |
707 if (counter && r->counter) | |
708 { | |
709 if (CPP_OPTION (r, warn_invalid_pch)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
710 cpp_warning_syshdr (r, CPP_W_INVALID_PCH, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
711 "%s: not used because `__COUNTER__' is invalid", |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
712 name); |
111 | 713 goto fail; |
0 | 714 } |
715 | |
716 /* We win! */ | |
717 return 0; | |
718 | |
719 error: | |
720 cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header"); | |
721 | |
722 fail: | |
111 | 723 free (namebuf); |
724 free (undeftab); | |
725 free (nl.defs); | |
0 | 726 return 1; |
727 } | |
728 | |
729 /* Save all the existing macros. */ | |
730 | |
731 struct save_macro_data | |
732 { | |
733 uchar **defns; | |
734 size_t count; | |
735 size_t array_size; | |
736 char **saved_pragmas; | |
737 }; | |
738 | |
739 /* Save the definition of a single macro, so that it will persist | |
740 across a PCH restore. Because macro data is in GCed memory, which | |
741 will be blown away by PCH, it must be temporarily copied to | |
742 malloced memory. (The macros will refer to identifier nodes which | |
743 are also GCed and so on, so the copying is done by turning them | |
744 into self-contained strings.) The assumption is that most macro | |
745 definitions will come from the PCH file, not from the compilation | |
746 before the PCH file is loaded, so it doesn't matter that this is | |
747 a little expensive. | |
748 | |
749 It would reduce the cost even further if macros defined in the PCH | |
750 file were not saved in this way, but this is not done (yet), except | |
751 for builtins, and for #assert by default. */ | |
752 | |
753 static int | |
754 save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) | |
755 { | |
756 struct save_macro_data *data = (struct save_macro_data *)data_p; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
757 |
131 | 758 if (cpp_user_macro_p (h)) |
0 | 759 { |
760 if (data->count == data->array_size) | |
761 { | |
762 data->array_size *= 2; | |
763 data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size)); | |
764 } | |
765 | |
131 | 766 const uchar * defn = cpp_macro_definition (r, h); |
767 size_t defnlen = ustrlen (defn); | |
0 | 768 |
131 | 769 data->defns[data->count] = (uchar *) xmemdup (defn, defnlen, defnlen + 2); |
770 data->defns[data->count][defnlen] = '\n'; | |
0 | 771 data->count++; |
772 } | |
131 | 773 |
0 | 774 return 1; |
775 } | |
776 | |
777 /* Prepare to restore the state, by saving the currently-defined | |
778 macros in 'data'. */ | |
779 | |
780 void | |
781 cpp_prepare_state (cpp_reader *r, struct save_macro_data **data) | |
782 { | |
783 struct save_macro_data *d = XNEW (struct save_macro_data); | |
784 | |
785 d->array_size = 512; | |
786 d->defns = XNEWVEC (uchar *, d->array_size); | |
787 d->count = 0; | |
788 cpp_forall_identifiers (r, save_macros, d); | |
789 d->saved_pragmas = _cpp_save_pragma_names (r); | |
790 *data = d; | |
791 } | |
792 | |
793 /* Given a precompiled header that was previously determined to be valid, | |
794 apply all its definitions (and undefinitions) to the current state. | |
795 DEPNAME is passed to deps_restore. */ | |
796 | |
797 int | |
798 cpp_read_state (cpp_reader *r, const char *name, FILE *f, | |
799 struct save_macro_data *data) | |
800 { | |
801 size_t i; | |
802 struct lexer_state old_state; | |
803 unsigned int counter; | |
804 | |
805 /* Restore spec_nodes, which will be full of references to the old | |
806 hashtable entries and so will now be invalid. */ | |
807 { | |
808 struct spec_nodes *s = &r->spec_nodes; | |
809 s->n_defined = cpp_lookup (r, DSC("defined")); | |
810 s->n_true = cpp_lookup (r, DSC("true")); | |
811 s->n_false = cpp_lookup (r, DSC("false")); | |
812 s->n__VA_ARGS__ = cpp_lookup (r, DSC("__VA_ARGS__")); | |
131 | 813 s->n__VA_OPT__ = cpp_lookup (r, DSC("__VA_OPT__")); |
0 | 814 } |
815 | |
816 old_state = r->state; | |
817 r->state.in_directive = 1; | |
818 r->state.prevent_expansion = 1; | |
819 r->state.angled_headers = 0; | |
820 | |
821 /* Run through the carefully-saved macros, insert them. */ | |
822 for (i = 0; i < data->count; i++) | |
823 { | |
824 cpp_hashnode *h; | |
825 size_t namelen; | |
826 uchar *defn; | |
827 | |
828 namelen = ustrcspn (data->defns[i], "( \n"); | |
829 h = cpp_lookup (r, data->defns[i], namelen); | |
830 defn = data->defns[i] + namelen; | |
831 | |
832 /* The PCH file is valid, so we know that if there is a definition | |
833 from the PCH file it must be the same as the one we had | |
834 originally, and so do not need to restore it. */ | |
835 if (h->type == NT_VOID) | |
836 { | |
837 if (cpp_push_buffer (r, defn, ustrchr (defn, '\n') - defn, true) | |
838 != NULL) | |
839 { | |
840 _cpp_clean_line (r); | |
841 if (!_cpp_create_definition (r, h)) | |
842 abort (); | |
843 _cpp_pop_buffer (r); | |
844 } | |
845 else | |
846 abort (); | |
847 } | |
848 | |
849 free (data->defns[i]); | |
850 } | |
851 r->state = old_state; | |
852 | |
853 _cpp_restore_pragma_names (r, data->saved_pragmas); | |
854 | |
855 free (data); | |
856 | |
857 if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL) | |
858 != 0) | |
859 goto error; | |
860 | |
861 if (! _cpp_read_file_entries (r, f)) | |
862 goto error; | |
863 | |
864 if (fread (&counter, sizeof (counter), 1, f) != 1) | |
865 goto error; | |
866 | |
867 if (!r->counter) | |
868 r->counter = counter; | |
869 | |
47
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
870 /* Read pushed macros. */ |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
871 if (! _cpp_restore_pushed_macros (r, f)) |
3bfb6c00c1e0
update it from 4.4.2 to 4.4.3.
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
872 goto error; |
0 | 873 return 0; |
874 | |
875 error: | |
876 cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header"); | |
877 return -1; | |
878 } |