Oranize the PPH tree switch into tcc_* chunks, in each of four sections:
[official-gcc.git] / gcc / cp / pph.c
blob4a9ee50326afe95e3385ed69111964d2599fcb18
1 /* Factored pre-parsed header (PPH) support for C++
2 Copyright (C) 2010, 2011 Free Software Foundation, Inc.
3 Contributed by Lawrence Crowl <crowl@google.com> and
4 Diego Novillo <dnovillo@google.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "cpplib.h"
26 #include "toplev.h"
27 #include "tree.h"
28 #include "cp-tree.h"
29 #include "timevar.h"
30 #include "pointer-set.h"
31 #include "fixed-value.h"
32 #include "md5.h"
33 #include "tree-pass.h"
34 #include "tree-dump.h"
35 #include "tree-inline.h"
36 #include "tree-pretty-print.h"
37 #include "parser.h"
38 #include "pph.h"
39 #include "pph-streamer.h"
41 /* Statistics collected for PTH/PPH. */
42 struct pth_stats_d pth_stats;
43 struct pph_stats_d pph_stats;
45 /* Forward declarations to solve cyclical references. */
46 static void pph_print_trees_tokens (VEC(tree,heap) *, cp_token *, cp_token *);
48 /* Map of decl dependencies. */
49 static struct pph_decl_deps_d *pph_decl_deps = NULL;
51 /* Tree catcher for the incremental compiler. Whenever this array is
52 allocated, make_node_stat() will push certain trees into this array. */
53 static VEC(tree,heap) *pph_tree_catcher = NULL;
55 /* Catcher for name lookups. This stores every name lookup performed
56 on identifiers while we are catching ASTs in the parser. */
57 static VEC(tree,heap) *pph_name_lookups = NULL;
59 /* Since identifiers may be looked up more than once during parsing,
60 this set prevents duplicate symbols from being placed in
61 pph_name_lookups. */
62 static struct pointer_set_t *pph_name_lookups_set = NULL;
64 /* This map stores the token locations where a given symbol was looked
65 up. When an identifier is looked up and resolved to symbol S, we
66 check where the current token pointer is and save it in a vector
67 associated with S. */
68 static struct pointer_map_t *pph_nl_token_map = NULL;
70 /* Log file where PPH analysis is written to. Controlled by
71 -fpph_logfile. If this flag is not given, stdout is used. */
72 FILE *pph_logfile = NULL;
74 /* Cache of token ranges for head of symbol declarations. For each
75 *_DECL tree intercepted during parsing, we store the vector of
76 tokens that make up the head of the declaration for the node. */
77 static struct pointer_map_t *pph_decl_head_token_cache = NULL;
79 /* Cache of token ranges for body of symbol declarations. For each
80 *_DECL tree intercepted during parsing, we store the vector of
81 tokens that make up the body of the declaration for the node. */
82 static struct pointer_map_t *pph_decl_body_token_cache = NULL;
85 /* Return true if path P1 and path P2 point to the same file. */
87 static inline bool
88 pathnames_equal_p (const char *p1, const char *p2)
90 return strcmp (lrealpath (p1), lrealpath (p2)) == 0;
93 /* Expand and print location LOC to FILE. If FILE is NULL, pph_logfile
94 is used. */
96 static void
97 pph_debug_location (FILE *file, location_t loc)
99 expanded_location xloc;
100 file = (file) ? file : pph_logfile;
101 xloc = expand_location (loc);
102 fprintf (file, "%s:%d:%d", lrealpath (xloc.file), xloc.line, xloc.column);
106 /* Expand and print the location of tree T to FILE. If FILE is NULL,
107 pph_logfile is used. */
109 static void
110 pph_debug_loc_of_tree (FILE *file, tree t)
112 pph_debug_location (file, DECL_SOURCE_LOCATION (t));
116 /* Hash and comparison functions for the directory of cached images. */
118 static hashval_t
119 pth_image_dir_hash (const void *p)
121 const char *s = lrealpath (((const pth_image *)p)->fname);
122 return htab_hash_string (s);
126 static int
127 pth_image_dir_eq (const void *p1, const void *p2)
129 const char *s1 = ((const pth_image *)p1)->fname;
130 const char *s2 = ((const pth_image *)p2)->fname;
131 return pathnames_equal_p (s1, s2);
135 static GTY(()) pth_state *pth_global_state = NULL;
137 /* Return the global PTH state where the cache and its directory
138 are stored. */
140 pth_state *
141 pth_get_state (void)
143 if (pth_global_state == NULL)
145 pth_global_state = ggc_alloc_cleared_pth_state ();
146 pth_global_state->cache_dir = htab_create_ggc (10, pth_image_dir_hash,
147 pth_image_dir_eq, NULL);
150 return pth_global_state;
154 /* Return an identification string for a PTH image. */
156 static const char *
157 pth_id_str (void)
159 /* FIXME pph - Build a better identification string. */
160 return "PTH0x42";
164 /* Return the number of bytes taken by the header of a PTH image. */
166 static size_t
167 pth_header_len (void)
169 /* The header of a PTH image contains:
170 - An identification string (pth_id_str ())
171 - The MD5 digest for the source file associated with the image.
173 return strlen (pth_id_str ()) + DIGEST_LEN;
177 #define PTH_EXTENSION ".pth"
179 /* Return a new string with the extension PTH_EXTENSION appended to NAME. The
180 caller is responsible for freeing the returned string. */
182 static char *
183 pth_name_for (const char *name)
185 size_t i, len;
186 char *s;
188 len = strlen (name) + sizeof (PTH_EXTENSION) + 1;
189 s = XCNEWVEC (char, len);
190 sprintf (s, "%s" PTH_EXTENSION, name);
192 /* Make the file name unique and store it in the current directory. */
193 for (i = 0; i < len - sizeof (PTH_EXTENSION) - 1; i++)
194 if (!ISALNUM (s[i]))
195 s[i] = '_';
197 return s;
201 /* Open an image file for path NAME. MODE is as in fopen. */
203 static pph_stream *
204 pth_file_for (const char *name, const char *mode)
206 char *s;
207 pph_stream *f;
209 s = pth_name_for (name);
210 f = pph_stream_open (s, mode);
211 if (!f)
212 fatal_error ("can%'t open token stream file %s: %m", s);
213 free (s);
215 return f;
219 /* Compute the MD5 digest for FNAME. Store it in DIGEST. */
221 static void
222 pth_get_md5_digest (const char *fname, unsigned char digest[DIGEST_LEN])
224 if (flag_pth_md5)
226 FILE *f;
228 timevar_push (TV_PTH_MD5);
230 f = fopen (fname, "rb");
231 if (f == NULL)
232 fatal_error ("Cannot open %s for computing its digest: %m", fname);
234 md5_stream (f, digest);
236 fclose (f);
238 timevar_pop (TV_PTH_MD5);
240 else
242 struct stat buf;
244 if (stat (fname,&buf) != 0)
245 fatal_error ("Cannot stat %s: %m", fname);
247 memset (digest, 0, DIGEST_LEN);
248 memcpy (digest, &buf.st_mtime, sizeof (buf.st_mtime));
253 /* Compute an index value for TYPE suitable for restoring it later
254 from global_trees[] or integer_types. The index is saved
255 in TYPE_IX_P and the number category (one of CPP_N_INTEGER,
256 CPP_N_FLOATING, etc) is saved in CATEGORY_P. */
258 static void
259 pth_get_index_from_type (tree type, unsigned *type_ix_p, unsigned *category_p)
261 void **val_p;
262 static struct pointer_map_t *type_cache = NULL;
264 /* For complex types we will just use the type of the components. */
265 if (TREE_CODE (type) == COMPLEX_TYPE)
267 *type_ix_p = 0;
268 *category_p = CPP_N_IMAGINARY;
269 return;
272 if (type_cache == NULL)
273 type_cache = pointer_map_create ();
275 val_p = pointer_map_contains (type_cache, type);
276 if (val_p)
277 *type_ix_p = *((unsigned *) val_p);
278 else
280 if (CP_INTEGRAL_TYPE_P (type))
282 unsigned i;
283 for (i = itk_char; i < itk_none; i++)
284 if (type == integer_types[i])
286 *type_ix_p = (unsigned) i;
287 break;
290 gcc_assert (i != itk_none);
292 else if (FLOAT_TYPE_P (type) || FIXED_POINT_TYPE_P (type))
294 unsigned i;
296 for (i = TI_ERROR_MARK; i < TI_MAX; i++)
297 if (global_trees[i] == type)
299 *type_ix_p = (unsigned) i;
300 break;
303 gcc_assert (i != TI_MAX);
305 else
306 gcc_unreachable ();
309 if (CP_INTEGRAL_TYPE_P (type))
310 *category_p = CPP_N_INTEGER;
311 else if (FLOAT_TYPE_P (type))
312 *category_p = CPP_N_FLOATING;
313 else if (FIXED_POINT_TYPE_P (type))
314 *category_p = CPP_N_FRACT;
315 else
316 gcc_unreachable ();
320 /* Save the number VAL to file F. */
322 static void
323 pth_write_number (pph_stream *f, tree val)
325 unsigned type_idx, type_kind;
327 pth_get_index_from_type (TREE_TYPE (val), &type_idx, &type_kind);
329 pph_output_uint (f, type_idx);
330 pph_output_uint (f, type_kind);
332 if (type_kind == CPP_N_INTEGER)
334 HOST_WIDE_INT v[2];
336 v[0] = TREE_INT_CST_LOW (val);
337 v[1] = TREE_INT_CST_HIGH (val);
338 pph_output_bytes (f, v, 2 * sizeof (HOST_WIDE_INT));
340 else if (type_kind == CPP_N_FLOATING)
342 REAL_VALUE_TYPE r = TREE_REAL_CST (val);
343 pph_output_bytes (f, &r, sizeof (REAL_VALUE_TYPE));
345 else if (type_kind == CPP_N_FRACT)
347 FIXED_VALUE_TYPE fv = TREE_FIXED_CST (val);
348 pph_output_bytes (f, &fv, sizeof (FIXED_VALUE_TYPE));
350 else if (type_kind == CPP_N_IMAGINARY)
352 pth_write_number (f, TREE_REALPART (val));
353 pth_write_number (f, TREE_IMAGPART (val));
355 else
356 gcc_unreachable ();
360 /* Save the tree associated with TOKEN to file F. */
362 static void
363 pth_save_token_value (pph_stream *f, cp_token *token)
365 const char *str;
366 unsigned len;
367 tree val;
369 val = token->u.value;
370 switch (token->type)
372 case CPP_TEMPLATE_ID:
373 case CPP_NESTED_NAME_SPECIFIER:
374 break;
376 case CPP_NAME:
377 /* FIXME pph. Hash the strings and emit a string table. */
378 str = IDENTIFIER_POINTER (val);
379 len = IDENTIFIER_LENGTH (val);
380 pph_output_string_with_length (f, str, len);
381 break;
383 case CPP_KEYWORD:
384 /* Nothing to do. We will reconstruct the keyword from
385 ridpointers[token->keyword] at load time. */
386 break;
388 case CPP_CHAR:
389 case CPP_WCHAR:
390 case CPP_CHAR16:
391 case CPP_CHAR32:
392 case CPP_NUMBER:
393 pth_write_number (f, val);
394 break;
396 case CPP_STRING:
397 case CPP_WSTRING:
398 case CPP_STRING16:
399 case CPP_STRING32:
400 /* FIXME pph. Need to represent the type. */
401 str = TREE_STRING_POINTER (val);
402 len = TREE_STRING_LENGTH (val);
403 pph_output_string_with_length (f, str, len);
404 break;
406 case CPP_PRAGMA:
407 /* Nothing to do. Field pragma_kind has already been written. */
408 break;
410 default:
411 gcc_assert (token->u.value == NULL);
412 pph_output_bytes (f, &token->u.value, sizeof (token->u.value));
417 /* Save TOKEN on file F. Return the number of bytes written on F. */
419 static void
420 pth_save_token (cp_token *token, pph_stream *f)
422 /* Do not write out the final field in TOKEN. It contains
423 pointers that need to be pickled separately.
425 FIXME pph - Need to also emit the location_t table so we can
426 reconstruct it when reading the PTH state. */
427 pph_output_bytes (f, token, sizeof (cp_token) - sizeof (void *));
428 pth_save_token_value (f, token);
432 /* Save all the tokens in CACHE to PPH stream F. */
434 void
435 pth_save_token_cache (cp_token_cache *cache, pph_stream *f)
437 unsigned i, num;
438 cp_token *tok;
440 if (cache == NULL)
442 pph_output_uint (f, 0);
443 return;
446 for (num = 0, tok = cache->first; tok != cache->last; tok++)
447 num++;
449 pph_output_uint (f, num);
450 for (i = 0, tok = cache->first; i < num; tok++, i++)
451 pth_save_token (tok, f);
455 /* Write header information for IMAGE to STREAM. */
457 static void
458 pth_write_header (pth_image *image, pph_stream *stream)
460 const char *id = pth_id_str ();
462 if (!image->digest_computed_p)
464 pth_get_md5_digest (image->fname, image->digest);
465 image->digest_computed_p = true;
468 pph_output_bytes (stream, id, strlen (id));
469 pph_output_bytes (stream, image->digest, DIGEST_LEN);
473 /* Dump a table of IDENTIFIERS to the STREAM. */
475 static void
476 pth_dump_identifiers (FILE *stream, cpp_idents_used *identifiers)
478 unsigned int idx, col = 1;
479 char use, exp;
481 fprintf (stream, "%u identifiers up to %u chars, vals to %u chars\n",
482 identifiers->num_entries, identifiers->max_ident_len,
483 identifiers->max_value_len);
484 for (idx = 0; idx < identifiers->num_entries; ++idx)
486 cpp_ident_use *ident = identifiers->entries + idx;
488 if (col + ident->ident_len >= 80)
490 fprintf (stream, "\n");
491 col = 1;
493 use = ident->used_by_directive ? 'U' : '-';
494 exp = ident->expanded_to_text ? 'E' : '-';
495 if (ident->before_str || ident->after_str)
497 if (col > 1)
498 fprintf (stream, "\n");
499 fprintf (stream, " %s %c%c = %s -> %s\n", ident->ident_str, use, exp,
500 ident->before_str, ident->after_str);
501 col = 1;
503 else
505 fprintf (stream, " %s %c%c", ident->ident_str, use, exp);
506 col += ident->ident_len;
509 fprintf (stream, "\n");
512 /* Dump a debug log of the IDENTIFIERS. */
514 void
515 pth_debug_identifiers (cpp_idents_used *identifiers);
517 void
518 pth_debug_identifiers (cpp_idents_used *identifiers)
520 pth_dump_identifiers (stderr, identifiers);
523 /* Dump a HUNK to the STREAM. */
525 static void
526 pth_dump_hunk (FILE *stream, cp_token_hunk *hunk)
528 pth_dump_identifiers (stream, &hunk->identifiers);
529 cp_lexer_dump_tokens (stream, hunk->buffer, NULL, 0, NULL);
532 /* Dump a debug log of the HUNK. */
534 static void
535 pth_debug_hunk (cp_token_hunk *hunk)
537 pth_dump_hunk (stderr, hunk);
541 /* Dump #include command INCLUDE to FILE. */
543 static void
544 pth_dump_include (FILE *f, pth_include *include)
546 if (include == NULL)
547 return;
549 if (include->itype == IT_INCLUDE)
550 fprintf (f, "#include ");
551 else if (include->itype == IT_INCLUDE_NEXT)
552 fprintf (f, "#include_next ");
553 else if (include->itype == IT_IMPORT)
554 fprintf (f, "#import ");
555 else
556 fprintf (f, "#??? ");
558 fprintf (f, "%c%s%c",
559 (include->angle_brackets) ? '<' : '"',
560 include->iname,
561 (include->angle_brackets) ? '>' : '"');
563 fprintf (f, " (found in %s)\n", include->dname);
567 /* Dump #include command INCLUDE to stderr. */
569 static void
570 pth_debug_include (pth_include *include)
572 pth_dump_include (stderr, include);
576 /* Recursive helper for pth_dump_token_hunks_1. VISITED keeps track of
577 images that have already been dumped to avoid infinite recursion. */
579 static void
580 pth_dump_token_hunks_1 (FILE *f, pth_image *image,
581 struct pointer_set_t *visited)
583 unsigned i, h_ix, i_ix;
584 char s;
586 if (pointer_set_insert (visited, image))
587 return;
589 fprintf (f, "LC_ENTER: %s {\n", image->fname);
591 for (i = 0, h_ix = 0, i_ix = 0;
592 VEC_iterate (char, image->ih_sequence, i, s);
593 i++)
595 if (s == 'H')
597 cp_token_hunk *hunk;
598 hunk = VEC_index (cp_token_hunk_ptr, image->token_hunks, h_ix++);
599 pth_dump_hunk (f, hunk);
601 else if (s == 'I')
603 pth_include *include;
604 include = VEC_index (pth_include_ptr, image->includes, i_ix++);
605 pth_dump_include (f, include);
606 pth_dump_token_hunks_1 (f, include->image, visited);
610 fprintf (f, "LC_LEAVE: %s }\n", image->fname);
614 /* Dump all the tokens in IMAGE and the files included by it to F. */
616 static void
617 pth_dump_token_hunks (FILE *f, pth_image *image)
619 struct pointer_set_t *visited = pointer_set_create ();
620 pth_dump_token_hunks_1 (f, image, visited);
621 pointer_set_destroy (visited);
625 /* Dump all the tokens in IMAGE and the files included by it to stderr. */
627 void
628 pth_debug_token_hunks (pth_image *image)
630 pth_dump_token_hunks (stderr, image);
634 /* Dump a debugging representation of IMAGE to F. */
636 static void
637 pth_dump_image (FILE *f, pth_image *image)
639 unsigned i;
640 cp_token_hunk *hunk;
641 pth_include *include;
642 char s;
644 if (image == NULL)
645 return;
647 fprintf (f, "Image for: %s\n", image->fname);
649 fprintf (f, " MD5 digest: ");
650 if (image->digest_computed_p)
652 for (i = 0; i < DIGEST_LEN; i++)
653 fprintf (f, "%02x", image->digest[i]);
654 fprintf (f, "\n");
656 else
657 fprintf (f, "NOT COMPUTED\n");
659 fprintf (f, " %u token hunks: { ",
660 VEC_length (cp_token_hunk_ptr, image->token_hunks));
661 for (i = 0; VEC_iterate (cp_token_hunk_ptr, image->token_hunks, i, hunk); i++)
662 fprintf (f, "%u ", VEC_length (cp_token, hunk->buffer));
663 fprintf (f, "}\n");
665 fprintf (f, " %u includes:\n",
666 VEC_length (pth_include_ptr, image->includes));
667 for (i = 0; VEC_iterate (pth_include_ptr, image->includes, i, include); i++)
669 fprintf (f, "\t");
670 pth_dump_include (f, include);
673 fprintf (f, " Include-Hunk (IH) sequence: ");
674 for (i = 0; VEC_iterate (char, image->ih_sequence, i, s); i++)
675 fputc (s, f);
676 fputc ('\n', f);
678 if (image->loaded_p)
679 fprintf (f, " Instantiated from image: %s\n", pth_name_for (image->fname));
680 else
682 fprintf (f, " Instantiated from character stream: %s\n", image->fname);
684 if (image->save_p)
685 fprintf (f, " Will be saved to image: %s\n",
686 pth_name_for (image->fname));
687 else
688 fprintf (f, " Will NOT be saved to an image (not include-guarded)\n");
691 if (image->used_p)
692 fprintf (f, " Image already applied to current compilation context\n");
694 if (flag_pth_debug >= 4)
695 pth_dump_token_hunks (f, image);
699 /* Dump a debugging representation of IMAGE to stderr. */
701 static void
702 pth_debug_image (pth_image *image)
704 pth_dump_image (stderr, image);
708 /* Show statistics for PTH image IMAGE on FILE. if FILE is NULL, use
709 pph_logfile. */
711 static void
712 pth_show_image_stats (FILE *file, pth_image *image)
714 unsigned i, num_tokens;
715 cp_token_hunk *hunk;
717 if (image == NULL)
718 return;
720 if (file == NULL)
721 file = pph_logfile;
723 num_tokens = 0;
724 for (i = 0; VEC_iterate (cp_token_hunk_ptr, image->token_hunks, i, hunk); i++)
725 num_tokens += VEC_length (cp_token, hunk->buffer);
727 fprintf (file, "%s: %u tokens, %u token hunks\n", image->fname, num_tokens,
728 VEC_length (cp_token_hunk_ptr, image->token_hunks));
732 /* Dump the current PTH state to F. */
734 static void
735 pth_dump_state (FILE *f)
737 unsigned i;
738 pth_state *state;
739 pth_image *image;
741 state = pth_get_state ();
742 fprintf (f, "Incremental compilation state\n\n");
743 fprintf (f, "%u file images\n", VEC_length (pth_image_ptr, state->cache));
744 for (i = 0; VEC_iterate (pth_image_ptr, state->cache, i, image); i++)
745 pth_dump_image (f, image);
747 fprintf (f, "\nCurrent image being processed: %s\n",
748 (state->cur_image) ? state->cur_image->fname : "NONE");
750 if (state->lexer)
752 fprintf (f, "Tokens in main lexer:\n");
753 cp_lexer_dump_tokens (f, state->lexer->buffer, NULL, 0, NULL);
758 /* Dump the current PTH state to stderr. */
760 void
761 pth_debug_state (void)
763 pth_dump_state (stderr);
767 /* Save the IDENTIFIERS to the STREAM. */
769 static void
770 pth_save_identifiers (cpp_idents_used *identifiers, pph_stream *stream)
772 unsigned int num_entries, active_entries, id;
774 num_entries = identifiers->num_entries;
775 pph_output_uint (stream, identifiers->max_ident_len);
776 pph_output_uint (stream, identifiers->max_value_len);
778 active_entries = 0;
779 for ( id = 0; id < num_entries; ++id )
781 cpp_ident_use *entry = identifiers->entries + id;
782 if (!(entry->used_by_directive || entry->expanded_to_text))
783 continue;
784 ++active_entries;
787 pph_output_uint (stream, active_entries);
789 for ( id = 0; id < num_entries; ++id )
791 cpp_ident_use *entry = identifiers->entries + id;
793 if (!(entry->used_by_directive || entry->expanded_to_text))
794 continue;
796 /* FIXME pph: We are wasting space; ident_len, used_by_directive
797 and expanded_to_text together could fit into a single uint. */
799 pph_output_uint (stream, entry->used_by_directive);
800 pph_output_uint (stream, entry->expanded_to_text);
802 gcc_assert (entry->ident_len <= identifiers->max_ident_len);
803 pph_output_string_with_length (stream, entry->ident_str,
804 entry->ident_len);
806 gcc_assert (entry->before_len <= identifiers->max_value_len);
807 pph_output_string_with_length (stream, entry->before_str,
808 entry->before_len);
810 gcc_assert (entry->after_len <= identifiers->max_value_len);
811 pph_output_string_with_length (stream, entry->after_str,
812 entry->after_len);
816 /* Save the HUNK to the STREAM. */
818 static void
819 pth_save_hunk (cp_token_hunk *hunk, pph_stream *stream)
821 unsigned j;
822 cp_token *token;
824 if (flag_pth_debug >= 5)
825 pth_debug_hunk (hunk);
827 /* Write out the identifiers used by HUNK. */
828 pth_save_identifiers (&hunk->identifiers, stream);
830 /* Write the number of tokens in HUNK. */
831 pph_output_uint (stream, VEC_length (cp_token, hunk->buffer));
833 /* Write the tokens. */
834 for (j = 0; VEC_iterate (cp_token, hunk->buffer, j, token); j++)
835 pth_save_token (token, stream);
839 /* Save the #include directive INCLUDE to STREAM. */
841 static void
842 pth_save_include (pth_include *include, pph_stream *stream)
844 pph_output_string (stream, include->image->fname);
845 pph_output_uint (stream, (unsigned int) include->itype);
846 pph_output_uint (stream, include->angle_brackets);
847 pph_output_string (stream, include->iname);
848 pph_output_string (stream, include->dname);
852 /* Save the PTH image IMAGE to a file. */
854 static void
855 pth_save_image (pth_image *image)
857 pph_stream *stream;
858 cp_token_hunk *hunk;
859 unsigned i, num;
860 pth_include *include;
862 timevar_push (TV_PTH_SAVE);
864 /* Open the stream in append mode since we have already created
865 it in pth_new_image. */
866 stream = pth_file_for (image->fname, "wb");
868 /* Write a header to recognize the file later. */
869 pth_write_header (image, stream);
871 /* Write the include-hunk (IH) sequencing vector. */
872 num = VEC_length (char, image->ih_sequence);
873 pph_output_uint (stream, num);
874 if (num > 0)
875 pph_output_bytes (stream, VEC_address (char, image->ih_sequence), num);
877 /* Write the number of #include commands. */
878 pph_output_uint (stream, VEC_length (pth_include_ptr, image->includes));
880 /* Write all the #include commands used by IMAGE. */
881 for (i = 0; VEC_iterate (pth_include_ptr, image->includes, i, include); i++)
882 pth_save_include (include, stream);
884 /* Write the number of token caches in the cache. */
885 pph_output_uint (stream, VEC_length (cp_token_hunk_ptr, image->token_hunks));
887 /* Write all the token hunks in image. */
888 for (i = 0; VEC_iterate (cp_token_hunk_ptr, image->token_hunks, i, hunk); i++)
889 pth_save_hunk (hunk, stream);
891 /* Clean up. */
892 pph_stream_close (stream);
893 image->save_p = false;
895 if (flag_pth_debug >= 3)
897 fprintf (stderr, "\nSaved image for %s:\n", image->fname);
898 pth_debug_image (image);
901 timevar_pop (TV_PTH_SAVE);
905 /* Given a type index TYPE_IDX and TYPE_KIND specifying the kind of type,
906 return a type from integer_types or global_trees. */
908 static tree
909 pth_get_type_from_index (unsigned type_idx, unsigned type_kind)
911 if (type_kind == CPP_N_INTEGER)
912 return integer_types[type_idx];
913 else if (type_kind == CPP_N_FLOATING || type_kind == CPP_N_FRACT)
914 return global_trees[type_idx];
915 else if (type_kind == CPP_N_IMAGINARY)
917 /* We don't need a type for the complex number. The type is
918 associated with the real and imaginary parts. */
919 return NULL_TREE;
921 else
922 gcc_unreachable ();
926 /* Load a numeric value from file F. Return the corresponding tree. */
928 static tree
929 pth_load_number (pph_stream *f)
931 unsigned type_idx, type_kind;
932 tree type, val;
934 type_idx = pph_input_uint (f);
935 type_kind = pph_input_uint (f);
937 type = pth_get_type_from_index (type_idx, type_kind);
939 if (type_kind == CPP_N_INTEGER)
941 HOST_WIDE_INT v[2];
942 pph_input_bytes (f, v, 2 * sizeof (HOST_WIDE_INT));
943 val = build_int_cst_wide (type, v[0], v[1]);
945 else if (type_kind == CPP_N_FLOATING)
947 REAL_VALUE_TYPE r;
948 pph_input_bytes (f, &r, sizeof (REAL_VALUE_TYPE));
949 val = build_real (type, r);
951 else if (type_kind == CPP_N_FRACT)
953 FIXED_VALUE_TYPE fv;
954 pph_input_bytes (f, &fv, sizeof (FIXED_VALUE_TYPE));
955 val = build_fixed (type, fv);
957 else if (type_kind == CPP_N_IMAGINARY)
959 tree r = pth_load_number (f);
960 tree i = pth_load_number (f);
961 val = build_complex (NULL_TREE, r, i);
963 else
964 gcc_unreachable ();
966 return val;
970 /* Load the tree value associated with TOKEN to file F. */
972 static void
973 pth_load_token_value (cp_token *token, pph_stream *f)
975 const char *str;
977 switch (token->type)
979 case CPP_TEMPLATE_ID:
980 case CPP_NESTED_NAME_SPECIFIER:
981 break;
983 case CPP_NAME:
984 str = pph_input_string (f);
985 token->u.value = get_identifier (str);
986 break;
988 case CPP_KEYWORD:
989 token->u.value = ridpointers[token->keyword];
990 break;
992 case CPP_CHAR:
993 case CPP_WCHAR:
994 case CPP_CHAR16:
995 case CPP_CHAR32:
996 case CPP_NUMBER:
997 token->u.value = pth_load_number (f);
998 break;
1000 case CPP_STRING:
1001 case CPP_WSTRING:
1002 case CPP_STRING16:
1003 case CPP_STRING32:
1004 str = pph_input_string (f);
1005 token->u.value = build_string (strlen (str), str);
1006 break;
1008 case CPP_PRAGMA:
1009 /* Nothing to do. Field pragma_kind has already been loaded. */
1010 break;
1012 default:
1013 pph_input_bytes (f, &token->u.value, sizeof (token->u.value));
1014 gcc_assert (token->u.value == NULL);
1019 /* Read and return a token from STREAM. */
1021 static cp_token *
1022 pth_load_token (pph_stream *stream)
1024 cp_token *token = ggc_alloc_cleared_cp_token ();
1026 /* Do not read the whole structure, the token value has
1027 dynamic size as it contains swizzled pointers.
1028 FIXME pph, restructure to allow bulk reads of the whole
1029 section. */
1030 pph_input_bytes (stream, token, sizeof (cp_token) - sizeof (void *));
1032 /* FIXME pph. Use an arbitrary (but valid) location to avoid
1033 confusing the rest of the compiler for now. */
1034 token->location = input_location;
1036 /* FIXME pph: verify that pth_load_token_value works with no tokens. */
1037 pth_load_token_value (token, stream);
1039 return token;
1043 /* Read and return a cp_token_cache instance from STREAM. */
1045 cp_token_cache *
1046 pth_load_token_cache (pph_stream *stream)
1048 unsigned i, num;
1049 cp_token *first, *last;
1051 num = pph_input_uint (stream);
1052 for (last = first = NULL, i = 0; i < num; i++)
1054 last = pth_load_token (stream);
1055 if (first == NULL)
1056 first = last;
1059 return cp_token_cache_new (first, last);
1063 /* Load the IDENTIFERS for a hunk from a STREAM. */
1065 static void
1066 pth_load_identifiers (cpp_idents_used *identifiers, pph_stream *stream)
1068 unsigned int j;
1069 unsigned int max_ident_len, max_value_len, num_entries;
1070 unsigned int ident_len, before_len, after_len;
1072 max_ident_len = pph_input_uint (stream);
1073 identifiers->max_ident_len = max_ident_len;
1074 max_value_len = pph_input_uint (stream);
1075 identifiers->max_value_len = max_value_len;
1076 num_entries = pph_input_uint (stream);
1077 identifiers->num_entries = num_entries;
1078 identifiers->entries = XCNEWVEC (cpp_ident_use, num_entries);
1079 identifiers->strings = XCNEW (struct obstack);
1081 /* Strings need no alignment. */
1082 _obstack_begin (identifiers->strings, 0, 0,
1083 (void *(*) (long)) xmalloc,
1084 (void (*) (void *)) free);
1085 obstack_alignment_mask (identifiers->strings) = 0;
1086 /* FIXME pph: We probably need to free all these things somewhere. */
1088 /* Read the identifiers in HUNK. */
1089 for (j = 0; j < num_entries; ++j)
1091 const char *s;
1092 identifiers->entries[j].used_by_directive = pph_input_uint (stream);
1093 identifiers->entries[j].expanded_to_text = pph_input_uint (stream);
1094 s = pph_input_string (stream);
1095 gcc_assert (s);
1096 ident_len = strlen (s);
1097 identifiers->entries[j].ident_len = ident_len;
1098 identifiers->entries[j].ident_str =
1099 (const char *) obstack_copy0 (identifiers->strings, s, ident_len);
1101 s = pph_input_string (stream);
1102 if (s)
1104 before_len = strlen (s);
1105 identifiers->entries[j].before_len = before_len;
1106 identifiers->entries[j].before_str = (const char *)
1107 obstack_copy0 (identifiers->strings, s, before_len);
1109 else
1111 /* The identifier table expects NULL entries to have
1112 a length of -1U. */
1113 identifiers->entries[j].before_len = -1U;
1114 identifiers->entries[j].before_str = NULL;
1117 s = pph_input_string (stream);
1118 if (s)
1120 after_len = strlen (s);
1121 identifiers->entries[j].after_len = after_len;
1122 identifiers->entries[j].after_str = (const char *)
1123 obstack_copy0 (identifiers->strings, s, after_len);
1125 else
1127 /* The identifier table expects NULL entries to have
1128 a length of -1U. */
1129 identifiers->entries[j].after_len = -1U;
1130 identifiers->entries[j].after_str = NULL;
1136 /* Load a hunk into the IMAGE from a STREAM. */
1138 static void
1139 pth_load_hunk (pth_image *image, pph_stream *stream)
1141 unsigned j, num_tokens;
1142 cp_token_hunk *hunk;
1144 hunk = ggc_alloc_cleared_cp_token_hunk ();
1146 /* Setup the identifier list. */
1147 pth_load_identifiers (&hunk->identifiers, stream);
1149 /* Read the number of tokens in HUNK. */
1150 num_tokens = pph_input_uint (stream);
1152 /* Read the tokens in the HUNK. */
1153 hunk->buffer = VEC_alloc (cp_token, gc, num_tokens);
1154 for (j = 0; j < num_tokens; j++)
1156 cp_token *token = pth_load_token (stream);
1157 VEC_quick_push (cp_token, hunk->buffer, token);
1159 gcc_assert (num_tokens == VEC_length (cp_token, hunk->buffer));
1161 VEC_quick_push (cp_token_hunk_ptr, image->token_hunks, hunk);
1165 /* Create a new empty #include directive for NAME. ITYPE is one of
1166 the supported include commands. ANGLE_BRACKETS is true if the
1167 include used '<>'. */
1169 static pth_include *
1170 pth_create_include (enum include_type itype, bool angle_brackets,
1171 const char *name)
1173 pth_include *include = ggc_alloc_cleared_pth_include ();
1174 include->itype = itype;
1175 include->angle_brackets = angle_brackets;
1176 include->iname = (name) ? xstrdup (name) : name;
1178 return include;
1182 /* Load an #include directive for IMAGE from STREAM. */
1184 static void
1185 pth_load_include (pth_state *state, pth_image *image, cpp_reader *reader,
1186 pph_stream *stream)
1188 const char *s;
1189 pth_include *include;
1190 unsigned tmp;
1192 include = pth_create_include (IT_INCLUDE, false, NULL);
1194 s = pph_input_string (stream);
1195 include->image = pth_image_lookup (state, s, reader);
1197 tmp = pph_input_uint (stream);
1198 include->itype = (enum include_type) tmp;
1200 tmp = pph_input_uint (stream);
1201 include->angle_brackets = (tmp != 0);
1203 include->iname = pph_input_string (stream);
1204 include->dname = pph_input_string (stream);
1206 VEC_safe_push (pth_include_ptr, gc, image->includes, include);
1210 /* Load a PTH image for LEXER using the READER. */
1212 static void
1213 pth_load_image (pth_state *state, pth_image *image, cpp_reader *reader)
1215 pph_stream *stream;
1216 unsigned i, num;
1217 char *buf;
1219 timevar_push (TV_PTH_LOAD);
1221 stream = pth_file_for (image->fname, "rb");
1223 /* Skip over the header, as we assume that it has already been
1224 validated by pth_have_valid_image_for. */
1225 buf = XCNEWVEC (char, pth_header_len ());
1226 pph_input_bytes (stream, buf, pth_header_len ());
1227 free (buf);
1229 /* Read the include-hunk (IH) sequencing vector. */
1230 num = pph_input_uint (stream);
1231 if (num > 0)
1233 image->ih_sequence = VEC_alloc (char, gc, num);
1234 VEC_safe_grow (char, gc, image->ih_sequence, num);
1235 pph_input_bytes (stream, VEC_address (char, image->ih_sequence), num);
1238 /* Read the number path names of all the files #included by
1239 IMAGE->FNAME. */
1240 num = pph_input_uint (stream);
1241 image->includes = VEC_alloc (pth_include_ptr, gc, num);
1243 /* Now read all the path names #included by IMAGE->FNAME. */
1244 for (i = 0; i < num; i++)
1245 pth_load_include (state, image, reader, stream);
1247 /* Read how many token hunks are contained in this image. */
1248 num = pph_input_uint (stream);
1249 image->token_hunks = VEC_alloc (cp_token_hunk_ptr, gc, num);
1251 PTH_STATS_INCR (hunks, num);
1253 /* Read all the token hunks. */
1254 for (i = 0; i < num; i++)
1255 pth_load_hunk (image, stream);
1257 pph_stream_close (stream);
1259 /* Indicate that we have loaded this image from a file. */
1260 image->loaded_p = true;
1261 image->save_p = false;
1262 image->used_p = false;
1264 if (flag_pth_debug >= 3)
1266 fprintf (stderr, "\nLoaded image for %s:\n", image->fname);
1267 pth_debug_image (image);
1270 timevar_pop (TV_PTH_LOAD);
1274 /* Return true if FNAME has a PTH image that can be used. If an image
1275 already exists, compute the MD5 digest for FNAME and store it
1276 in IMAGE. */
1278 static bool
1279 pth_have_valid_image_for (const char *fname, pth_image *image)
1281 pph_stream *f = NULL;
1282 struct stat s;
1283 char *img_name, *id;
1284 const char *good_id;
1285 char saved_digest[DIGEST_LEN];
1287 image->digest_computed_p = false;
1289 img_name = pth_name_for (fname);
1290 if (stat (img_name, &s) != 0)
1291 goto invalid_img;
1293 /* If the file exists, check if it has a valid signature. */
1294 f = pph_stream_open (img_name, "rb");
1295 gcc_assert (f);
1297 good_id = pth_id_str ();
1298 id = XCNEWVEC (char, strlen (good_id) + 1);
1299 pph_input_bytes (f, id, strlen (good_id));
1300 if (strcmp (id, good_id) != 0)
1301 goto invalid_img;
1303 /* Now check if the MD5 digest stored in the image file matches the
1304 digest for FNAME. */
1305 pph_input_bytes (f, saved_digest, DIGEST_LEN);
1306 pth_get_md5_digest (fname, image->digest);
1307 image->digest_computed_p = true;
1308 if (memcmp (image->digest, saved_digest, DIGEST_LEN) != 0)
1309 goto invalid_img;
1311 pph_stream_close (f);
1312 return true;
1314 invalid_img:
1315 if (f)
1316 pph_stream_close (f);
1318 return false;
1322 /* Create a new PTH cache object for file FNAME. */
1324 static pth_image *
1325 pth_new_image (const char *fname)
1327 pth_image *image;
1329 image = ggc_alloc_cleared_pth_image ();
1330 image->fname = xstrdup (fname);
1332 return image;
1336 /* Return a cache image associated with file FNAME. STATE holds
1337 the PTH cache to use. */
1339 pth_image *
1340 pth_image_lookup (pth_state *state, const char *fname, cpp_reader *reader)
1342 void **slot;
1343 pth_image *image, e;
1345 if (fname == NULL)
1346 return NULL;
1348 e.fname = fname;
1349 slot = htab_find_slot (state->cache_dir, &e, INSERT);
1350 if (*slot == NULL)
1352 /* Create a new image and store it in the cache. */
1353 image = pth_new_image (fname);
1354 *slot = image;
1355 VEC_safe_push (pth_image_ptr, gc, state->cache, image);
1357 /* If a valid disk image already exists for FNAME, load it.
1358 Otherwise, mark the memory image for processing and saving. */
1359 if (pth_have_valid_image_for (fname, image))
1360 pth_load_image (state, image, reader);
1361 else
1362 image->save_p = true;
1364 else
1365 image = *((pth_image **) slot);
1367 return image;
1371 /* Add all the tokens in HUNK to the end of LEXER->BUFFER. IMAGE is
1372 the memory image holding HUNK. */
1374 static void
1375 pth_append_hunk (cp_lexer *lexer, cp_token_hunk *hunk)
1377 cp_token *lexer_addr, *hunk_addr;
1378 unsigned lexer_len, hunk_len;
1380 PTH_STATS_INCR (valid_hunks, 1);
1382 /* Apply all the identifiers used and defined by HUNK. */
1383 cpp_lt_replay (parse_in, &hunk->identifiers);
1385 hunk_len = VEC_length (cp_token, hunk->buffer);
1387 /* Some hunks have no tokens and they are only useful for the
1388 macros defined by them. This is useful when one or more
1389 image files are tainted and need to be restored from their
1390 character stream. */
1391 if (hunk_len == 0)
1392 return;
1394 /* Determine the last location in LEXER->BUFFER before growing it. */
1395 lexer_len = VEC_length (cp_token, lexer->buffer);
1396 VEC_safe_grow (cp_token, gc, lexer->buffer, lexer_len + hunk_len);
1398 /* Bulk copy all the tokens in HUNK to the end of LEXER->BUFFER. */
1399 lexer_addr = VEC_address (cp_token, lexer->buffer);
1400 hunk_addr = VEC_address (cp_token, hunk->buffer);
1401 memcpy (&lexer_addr[lexer_len], hunk_addr, hunk_len * sizeof (cp_token));
1403 if (flag_pth_debug >= 2)
1405 fprintf (stderr, "\n=> ADDED TOKEN HUNK TO LEXER BUFFER");
1406 if (flag_pth_debug >= 5)
1407 pth_debug_hunk (hunk);
1412 /* Return true if HUNK can be used in the current compilation
1413 context of the cpp READER. It must validate the identifier state. */
1415 static bool
1416 pth_hunk_is_valid_p (pth_image *image, cp_token_hunk *hunk, cpp_reader *reader)
1418 bool verified;
1419 cpp_ident_use *bad_use;
1420 const char *cur_def;
1422 timevar_push (TV_PTH_DEPENDENCY);
1423 verified = cpp_lt_verify (reader, &hunk->identifiers, &bad_use, &cur_def);
1424 if (!verified && flag_pth_debug >= 1)
1426 pth_debug_hunk (hunk);
1427 fprintf (stderr, "PTH: %s failed verification: %s : <%s> -> <%s>\n",
1428 pth_name_for (image->fname), bad_use->ident_str,
1429 bad_use->before_str, cur_def);
1431 PTH_STATS_INCR (verified_hunks, 1);
1432 PTH_STATS_INCR (verified_identifiers, hunk->identifiers.num_entries);
1433 timevar_pop (TV_PTH_DEPENDENCY);
1434 return verified;
1438 /* Return true if IMAGE can be used in the current compilation context. */
1440 static bool
1441 pth_image_can_be_used (pth_image *image)
1443 return image && image->loaded_p && !image->used_p;
1447 /* Split NAME into its directory and file name components, storing them
1448 in *DNAME_P and *FNAME_P. After using it, *DNAME_P should be freed
1449 by the caller. */
1451 static void
1452 pth_get_dir_and_name (const char *name, char **dname_p, const char **fname_p)
1454 size_t len;
1456 *fname_p = lbasename (name);
1457 *dname_p = NULL;
1459 len = *fname_p - name;
1460 if (len > 0)
1462 *dname_p = XNEWVEC (char, len + 1);
1463 memcpy (*dname_p, name, len);
1464 (*dname_p)[len] = '\0';
1465 gcc_assert (IS_DIR_SEPARATOR ((*dname_p)[len - 1]));
1470 /* Read tokens from the text stream in IMAGE->FNAME into LEXER.
1471 If INCLUDE is not NULL, it describes how IMAGE->FNAME was
1472 #included originally. Otherwise, it is assumed to be an
1473 include command done with the flag -include.
1475 This is used when we need to process an #include command from
1476 a PPH image and the file to be included is a regular text file. */
1478 static void
1479 pth_process_text_file (cp_lexer *lexer, pth_image *image, pth_include *include)
1481 bool pushed_p;
1482 cpp_buffer *buffer;
1484 /* Emulate a #include directive on IMAGE->FNAME, if needed. Note
1485 that if we are already inside the CPP buffer for IMAGE->FNAME
1486 we should not include it again, since this will cause another
1487 call to pth_file_change which will again register IMAGE->FNAME as
1488 an include for the parent file. */
1489 gcc_assert (image->buffer != cpp_get_buffer (parse_in));
1491 if (include == NULL || include->itype == IT_INCLUDE_NEXT)
1493 char *dname;
1494 const char *fname;
1495 pth_get_dir_and_name (image->fname, &dname, &fname);
1496 /* FIXME pph. We are leaking DNAME here. libcpp
1497 wants the directory name in permanent storage so we
1498 cannot free it, but we should put it in an obstack
1499 so it can be reclaimed at some point. */
1500 pushed_p = cpp_push_include_type (parse_in, dname, fname, false,
1501 IT_INCLUDE);
1503 else
1504 pushed_p = cpp_push_include_type (parse_in, include->dname, include->iname,
1505 include->angle_brackets, include->itype);
1507 /* Nothing else to do if libcpp decided it did not need the file. */
1508 if (!pushed_p)
1509 return;
1511 /* Position the reader at the start of the buffer and request to
1512 stop reading at the end of it. */
1513 buffer = cpp_get_buffer (parse_in);
1514 cpp_set_pos (buffer, cpp_buffer_start);
1515 cpp_return_at_eof (buffer, true);
1517 /* Get tokens from IMAGE->FNAME. */
1518 cp_lexer_get_tokens (lexer);
1520 /* Since we read this file separately, the very last token in LEXER
1521 will now contain an EOF, which we do not need. */
1522 VEC_pop (cp_token, lexer->buffer);
1523 cpp_return_at_eof (buffer, false);
1527 /* Populate LEXER->BUFFER with all the valid token hunks in
1528 IMAGE. If possible, try to load token hunks from files
1529 included by IMAGE as well.
1531 This means that we try to load the whole transitive closure
1532 starting at IMAGE until we find the first unloadable file.
1534 Once we find the first unloadable token hunk, we skip the token
1535 hunks from the character stream so that they don't need to be
1536 pre-processed again.
1538 If non-NULL, INCLUDE describes the #include command used to include
1539 IMAGE->FNAME. */
1541 static void
1542 pth_image_to_lexer (cp_lexer *lexer, pth_image *image, pth_include *include)
1544 unsigned i, h_ix, i_ix;
1545 char s;
1547 /* If we are trying to apply the same image more than once,
1548 something is wrong. We never create images for files that
1549 are included more than once, so we should never try to apply
1550 the same image more than once. */
1551 gcc_assert (pth_image_can_be_used (image));
1553 image->used_p = true;
1555 if (flag_pth_debug >= 2)
1557 fprintf (stderr, "\n<= INCORPORATING IMAGE %s INTO COMPILATION CONTEXT\n",
1558 image->fname);
1559 if (flag_pth_debug >= 3)
1560 pth_debug_include (include);
1563 PTH_STATS_INCR (valid_images, 1);
1565 for (i = 0, h_ix = 0, i_ix = 0;
1566 VEC_iterate (char, image->ih_sequence, i, s);
1567 i++)
1569 if (s == 'H')
1571 cp_token_hunk *hunk;
1573 hunk = VEC_index (cp_token_hunk_ptr, image->token_hunks, h_ix++);
1574 if (pth_hunk_is_valid_p (image, hunk, parse_in))
1575 pth_append_hunk (lexer, hunk);
1576 else
1577 fatal_error ("Found an invalid hunk in %s. This header file "
1578 "cannot be converted into a pre-parsed image.",
1579 image->fname);
1581 else if (s == 'I')
1583 pth_include *incdir;
1584 pth_get_state ()->cur_image = image;
1585 incdir = VEC_index (pth_include_ptr, image->includes, i_ix++);
1586 if (pth_image_can_be_used (incdir->image))
1587 pth_image_to_lexer (lexer, incdir->image, incdir);
1588 else
1589 pth_process_text_file (lexer, incdir->image, incdir);
1591 else
1592 gcc_unreachable ();
1595 /* If we just applied the tokens for the main input filename,
1596 we need to append a CPP_EOF token, since that one is never
1597 saved with the token hunks. */
1598 if (pathnames_equal_p (image->fname, main_input_filename))
1599 VEC_safe_push (cp_token, gc, lexer->buffer, &eof_token);
1601 /* If IMAGE has a libcpp buffer associated with it, it means that a
1602 file that was being pre-processed from text has #included IMAGE
1603 and the pre-processor has executed the file change logic.
1605 In that case, the pre-processor will want to finish processing
1606 IMAGE's text, and since we have just applied its tokens from
1607 the image, the result will be duplicate tokens. To prevent
1608 this, we tell libcpp to skip over the whole text buffer
1609 associated with IMAGE. */
1610 if (image->buffer)
1611 cpp_set_pos (image->buffer, cpp_buffer_end);
1613 return;
1617 /* Create a token hunk for IMAGE from the token buffer in
1618 LEXER->BUFFER. The hunk will contain all the tokens starting at
1619 IMAGE->HUNK_START_IX to the end of LEXER->BUFFER.
1621 The new token hunk will be added to the end of IMAGE->TOKEN_HUNKS. */
1623 static void
1624 pth_lexer_to_image (pth_image *image, cp_lexer *lexer, cpp_reader *reader)
1626 cp_token *lexer_addr, *hunk_addr;
1627 cp_token_hunk *hunk;
1628 unsigned num_tokens, start_ix, end_ix;
1630 /* Create a new token hunk. */
1631 hunk = ggc_alloc_cleared_cp_token_hunk ();
1632 VEC_safe_push (cp_token_hunk_ptr, gc, image->token_hunks, hunk);
1633 VEC_safe_push (char, gc, image->ih_sequence, 'H');
1635 /* The identifiers that may conflict with macros. */
1636 hunk->identifiers = cpp_lt_capture (reader);
1638 /* Compute the bounds for the new token hunk. */
1639 start_ix = image->hunk_start_ix;
1640 end_ix = VEC_length (cp_token, lexer->buffer);
1641 gcc_assert (end_ix >= start_ix);
1642 num_tokens = end_ix - start_ix;
1644 if (num_tokens > 0)
1646 /* Copy tokens from LEXER->BUFFER into the new hunk. */
1647 hunk->buffer = VEC_alloc (cp_token, gc, num_tokens);
1648 VEC_safe_grow (cp_token, gc, hunk->buffer, num_tokens);
1649 lexer_addr = VEC_address (cp_token, lexer->buffer);
1650 hunk_addr = VEC_address (cp_token, hunk->buffer);
1651 memcpy (hunk_addr, &lexer_addr[start_ix], num_tokens * sizeof (cp_token));
1654 if (flag_pth_debug >= 3)
1656 fprintf (stderr, "\n=> SAVED HUNK TO IMAGE: %s\n", image->fname);
1657 if (flag_pth_debug >= 5)
1658 pth_debug_hunk (hunk);
1663 /* Compute the effects of a file transition given the file change
1664 described by MAP. On exit:
1666 - *PREV_IMAGE_P will point to the image for the file that we just left,
1668 - *NEW_IMAGE_P will point to the image for the file that we just
1669 entered. If *NEW_IMAGE_P is NULL, it means that we just left
1670 the last file in the translation unit, so there isn't anything
1671 else to be done.
1673 - *REASON_P will have the LC_* reason for the change. */
1675 static void
1676 pth_get_file_transition (const struct line_map *map, pth_image **prev_image_p,
1677 pth_image **new_image_p, enum lc_reason *reason_p)
1679 const char *fname;
1680 pth_state *state;
1682 /* MAP is NULL when we leave the main file in this translation unit. */
1683 if (map == NULL)
1685 fname = NULL;
1686 *reason_p = LC_LEAVE;
1688 else
1690 fname = map->to_file;
1691 *reason_p = map->reason;
1694 state = pth_get_state ();
1695 *prev_image_p = state->cur_image;
1697 /* FIXME pph. Sanitize use of PARSE_IN. Stick it in
1698 pth_state together with lexer. */
1699 *new_image_p = pth_image_lookup (state, fname, parse_in);
1703 /* Do bookkeeping actions required when the pre-processor is leaving
1704 file IMAGE->FNAME. READER is the cpp file reader object we
1705 are using for lexing. */
1707 static void
1708 pth_leave_file (cpp_reader *reader, pth_image *image)
1710 pth_state *state;
1712 /* We are only interested in processing IMAGE if we have decided to
1713 save its image. */
1714 if (!image->save_p)
1715 return;
1717 state = pth_get_state ();
1719 /* If the image for the file we just finished is marked as
1720 modified, create a new token hunk spanning from the token
1721 that started the image to the current end of the lexer
1722 buffer. */
1723 pth_lexer_to_image (image, state->lexer, reader);
1727 /* Do bookkeeping actions required when the pre-processor is entering
1728 file IMAGE->FNAME for reason REASON. READER is the cpp file reader
1729 object we are using for lexing. INCLUDE is the #include command
1730 used to enter IMAGE->FNAME. It can be NULL in the case of the
1731 top file in the translation unit. */
1733 static void
1734 pth_enter_file (cpp_reader *reader, pth_image *image, pth_include *include,
1735 enum lc_reason reason)
1737 pth_state *state;
1739 state = pth_get_state ();
1741 /* Associate the current buffer with IMAGE. */
1742 image->buffer = cpp_get_buffer (reader);
1744 /* Complete the current #include command with the directory
1745 and image for the file that we just switched to. */
1746 if (include)
1748 const char *dname = cpp_get_dir (cpp_get_file (image->buffer))->name;
1749 include->image = image;
1750 include->dname = (*dname) ? xstrdup (dname) : NULL;
1753 /* If the file we are about to switch to has been loaded into an
1754 image, try to get as many tokens as possible from the image
1755 instead of the character stream. */
1756 if (pth_image_can_be_used (image))
1757 pth_image_to_lexer (state->lexer, image, include);
1759 /* If IMAGE does not need to be saved, we are done. */
1760 if (!image->save_p)
1761 return;
1763 /* Detect multiple inclusions of the same header file. When a file
1764 is included more than once, each inclusion will usually produce
1765 different token hunks (e.g., <stddef.h> is typically included
1766 from different places with "arguments" in the form of #defines
1767 that determine what the caller wants stddef.h to provide. See
1768 <wchar.h> for an example).
1770 This disrupts the validity of the image, as the hunks saved in it
1771 no longer correspond to a single pre-processing of the file. We
1772 avoid this problem by tainting the image and forcing the file to
1773 be always processed from its character stream. */
1774 if (reason == LC_ENTER && !VEC_empty (cp_token_hunk_ptr, image->token_hunks))
1775 image->save_p = false;
1777 /* The starting point for the next token hunk in the new
1778 file image will be at the current last slot in
1779 STATE->LEXER->BUFFER. */
1780 image->hunk_start_ix = VEC_length (cp_token, state->lexer->buffer);
1784 /* Callback from the pre-processor when changing in or out of a file.
1785 READER is the pre-processor state. MAP is the line map for the
1786 file that we are changing to. */
1788 static void
1789 pth_file_change (cpp_reader *reader, const struct line_map *map)
1791 enum lc_reason reason;
1792 pth_state *state;
1793 pth_image *prev_image, *new_image;
1795 /* Call the previous file change handler, if it exists. */
1796 state = pth_get_state ();
1797 if (state->file_change_prev)
1798 state->file_change_prev (reader, map);
1800 /* When processing pre-processed output, we will see names like
1801 '<built-in>' and '<command-line>'. Reject those.
1802 ??? This rejects real path names that may start with '<', but
1803 those should be rare. */
1804 if (map && map->to_file && map->to_file[0] == '<')
1805 return;
1807 /* Ignore LC_RENAME events. They do not affect the actual image
1808 that we are processing. */
1809 if (map && map->reason == LC_RENAME)
1810 return;
1812 timevar_push (TV_PTH_MANAGE);
1814 /* Get images for the file involved in the transition. */
1815 pth_get_file_transition (map, &prev_image, &new_image, &reason);
1816 gcc_assert (prev_image);
1818 /* Ignore self-referential file change events. These can happen
1819 when mixing token images with text buffers. */
1820 if (prev_image == new_image)
1822 timevar_pop (TV_PTH_MANAGE);
1823 return;
1826 /* Process the file we just left (get tokens from lexer buffer,
1827 etc). */
1828 pth_leave_file (reader, prev_image);
1830 /* Process the file we are about to enter (try to use its tokens if
1831 the file is valid, etc). */
1832 if (new_image)
1834 pth_include *include = NULL;
1836 if (reason == LC_ENTER)
1837 include = pth_create_include (state->new_itype,
1838 state->new_angle_brackets,
1839 state->new_iname);
1841 pth_enter_file (reader, new_image, include, reason);
1843 /* If we are LC_ENTERing NEW_IMAGE, it means that PREV_IMAGE has
1844 #included NEW_IMAGE. In that case, add NEW_IMAGE to the list
1845 of included files by PREV_IMAGE. */
1846 if (reason == LC_ENTER)
1848 PTH_STATS_INCR (included_files, 1);
1850 if (prev_image->save_p)
1852 gcc_assert (include->image == new_image);
1853 VEC_safe_push (pth_include_ptr, gc, prev_image->includes,
1854 include);
1855 VEC_safe_push (char, gc, prev_image->ih_sequence, 'I');
1860 /* Update the current image. */
1861 state->cur_image = new_image;
1863 timevar_pop (TV_PTH_MANAGE);
1867 /* Dump a complicated name for tree T to FILE using FLAGS.
1868 See TDF_* in tree-pass.h for flags. */
1870 static void
1871 pph_dump_tree_name (FILE *file, tree t, int flags)
1873 enum tree_code code = TREE_CODE (t);
1874 fprintf (file, "%s\t", tree_code_name[code]);
1875 if (code == FUNCTION_TYPE || code == METHOD_TYPE)
1877 dump_function_to_file (t, file, flags);
1879 else
1881 print_generic_expr (file, TREE_TYPE (t), flags);
1882 /* FIXME pph: fprintf (file, " ", cxx_printable_name (t, 0)); */
1883 fprintf (file, " " );
1884 print_generic_expr (file, t, flags);
1886 fprintf (file, "\n");
1890 /* Dump namespace NS for PPH. */
1892 static void
1893 pph_dump_namespace (FILE *file, tree ns)
1895 struct cp_binding_level *level;
1896 tree t, chain;
1897 level = NAMESPACE_LEVEL (ns);
1899 fprintf (file, "namespace ");
1900 print_generic_expr (file, ns, 0);
1901 fprintf (file, " {\n");
1902 for (t = level->names; t; t = chain)
1904 chain = DECL_CHAIN (t);
1905 if (!DECL_IS_BUILTIN (t))
1906 pph_dump_tree_name (file, t, 0);
1908 for (t = level->namespaces; t; t = chain)
1910 chain = DECL_CHAIN (t);
1911 if (!DECL_IS_BUILTIN (t))
1912 pph_dump_namespace (file, t);
1914 fprintf (file, "}\n");
1918 /* Write PPH output symbols and IDENTS_USED to STREAM as an object. */
1920 static void
1921 pph_write_file_contents (pph_stream *stream, cpp_idents_used *idents_used)
1923 pth_save_identifiers (idents_used, stream);
1924 if (flag_pph_dump_tree)
1925 pph_dump_namespace (pph_logfile, global_namespace);
1926 pph_output_tree (stream, global_namespace, false);
1927 pph_output_tree (stream, keyed_classes, false);
1928 pph_stream_write_tree_vec (stream, unemitted_tinfo_decls, false);
1932 /* Write PPH output file. */
1934 static void
1935 pph_write_file (void)
1937 pph_stream *stream;
1938 cpp_idents_used idents_used;
1940 if (flag_pph_debug >= 1)
1941 fprintf (pph_logfile, "PPH: Writing %s\n", pph_out_file);
1943 stream = pph_stream_open (pph_out_file, "wb");
1944 if (!stream)
1945 fatal_error ("Cannot open PPH file for writing: %s: %m", pph_out_file);
1947 idents_used = cpp_lt_capture (parse_in);
1948 pph_write_file_contents (stream, &idents_used);
1950 pph_stream_close (stream);
1954 /* Wrap a macro DEFINITION for printing in an error. */
1956 static char *
1957 wrap_macro_def (const char *definition)
1959 char *string;
1960 if (definition)
1962 size_t length;
1963 length = strlen (definition);
1964 string = (char *) xmalloc (length+3);
1965 string[0] = '"';
1966 strcpy (string + 1, definition);
1967 string[length + 1] = '"';
1968 string[length + 2] = '\0';
1970 else
1971 string = xstrdup ("undefined");
1972 return string;
1976 /* Report a macro validation error in FILENAME for macro IDENT,
1977 which should have the value EXPECTED but actually had the value FOUND. */
1979 static void
1980 report_validation_error (const char *filename,
1981 const char *ident, const char *found,
1982 const char *before, const char *after)
1984 char* quote_found = wrap_macro_def (found);
1985 char* quote_before = wrap_macro_def (before);
1986 char* quote_after = wrap_macro_def (after);
1987 error ("PPH file %s fails macro validation, "
1988 "%s is %s and should be %s or %s\n",
1989 filename, ident, quote_found, quote_before, quote_after);
1990 free (quote_found);
1991 free (quote_before);
1992 free (quote_after);
1997 /* Add all the new names declared in NEW_NS to NS. */
1999 static void
2000 pph_add_names_to_namespace (tree ns, tree new_ns)
2002 tree t, chain;
2003 struct cp_binding_level *level = NAMESPACE_LEVEL (new_ns);
2005 for (t = level->names; t; t = chain)
2007 /* Pushing a decl into a scope clobbers its DECL_CHAIN.
2008 Preserve it. */
2009 chain = DECL_CHAIN (t);
2010 pushdecl_into_namespace (t, ns);
2013 for (t = level->namespaces; t; t = chain)
2015 /* Pushing a decl into a scope clobbers its DECL_CHAIN.
2016 Preserve it. */
2017 /* FIXME pph: we should first check to see if it isn't already there. */
2018 chain = DECL_CHAIN (t);
2019 pushdecl_into_namespace (t, ns);
2020 pph_add_names_to_namespace (t, t);
2025 /* Read contents of PPH file in STREAM. */
2027 static void
2028 pph_read_file_contents (pph_stream *stream)
2030 bool verified;
2031 cpp_ident_use *bad_use;
2032 const char *cur_def;
2033 cpp_idents_used idents_used;
2034 tree file_ns;
2036 pth_load_identifiers (&idents_used, stream);
2038 /* FIXME pph: This validation is weak. */
2039 verified = cpp_lt_verify_1 (parse_in, &idents_used, &bad_use, &cur_def, true);
2040 if (!verified)
2041 report_validation_error (stream->name, bad_use->ident_str, cur_def,
2042 bad_use->before_str, bad_use->after_str);
2044 /* Re-instantiate all the pre-processor symbols defined by STREAM. */
2045 cpp_lt_replay (parse_in, &idents_used);
2047 /* Read global_namespace from STREAM and add all the names defined
2048 there to the current global_namespace. */
2049 file_ns = pph_input_tree (stream);
2050 if (flag_pph_dump_tree)
2051 pph_dump_namespace (pph_logfile, file_ns);
2052 pph_add_names_to_namespace (global_namespace, file_ns);
2053 keyed_classes = pph_input_tree (stream);
2054 unemitted_tinfo_decls = pph_stream_read_tree_vec (stream);
2055 /* FIXME pph: This call replaces the tinfo, we should merge instead.
2056 See pph_input_tree_VEC. */
2060 /* Read PPH file FILENAME. */
2062 static void
2063 pph_read_file (const char *filename)
2065 pph_stream *stream;
2067 if (flag_pph_debug >= 1)
2068 fprintf (pph_logfile, "PPH: Reading %s\n", filename);
2070 stream = pph_stream_open (filename, "rb");
2071 if (stream)
2073 pph_read_file_contents (stream);
2074 pph_stream_close (stream);
2076 if (flag_pph_debug >= 1)
2077 fprintf (pph_logfile, "PPH: Closing %s\n", filename);
2079 else
2080 error ("Cannot open PPH file for reading: %s: %m", filename);
2084 /* Record a #include or #include_next for PTH. */
2086 static bool
2087 pth_include_handler (cpp_reader *reader ATTRIBUTE_UNUSED,
2088 location_t loc ATTRIBUTE_UNUSED,
2089 const unsigned char *dname,
2090 const char *name,
2091 int angle_brackets,
2092 const cpp_token **tok_p ATTRIBUTE_UNUSED)
2094 pth_state *state;
2096 state = pth_get_state ();
2098 /* Remember the attributes for this #include command. This is
2099 used in pth_file_change to register a new include event for
2100 the parent file. */
2101 if (strcmp ((const char *)dname, "include") == 0)
2102 state->new_itype = IT_INCLUDE;
2103 else if (strcmp ((const char *)dname, "include_next") == 0)
2104 state->new_itype = IT_INCLUDE_NEXT;
2105 else if (strcmp ((const char *)dname, "import") == 0)
2106 state->new_itype = IT_IMPORT;
2107 else
2108 gcc_unreachable ();
2110 state->new_angle_brackets = angle_brackets;
2111 state->new_iname = name;
2113 return true;
2117 /* Record a #include or #include_next for PPH. */
2119 static bool
2120 pph_include_handler (cpp_reader *reader,
2121 location_t loc ATTRIBUTE_UNUSED,
2122 const unsigned char *dname,
2123 const char *name,
2124 int angle_brackets,
2125 const cpp_token **tok_p ATTRIBUTE_UNUSED)
2127 const char *pph_file;
2128 bool read_text_file_p;
2130 if (flag_pph_debug >= 1)
2132 fprintf (pph_logfile, "PPH: #%s", dname);
2133 fprintf (pph_logfile, " %c", angle_brackets ? '<' : '"');
2134 fprintf (pph_logfile, "%s", name);
2135 fprintf (pph_logfile, "%c\n", angle_brackets ? '>' : '"');
2138 read_text_file_p = true;
2139 pph_file = query_pph_include_map (name);
2140 if (pph_file != NULL && !cpp_included_before (reader, name, input_location))
2142 pph_read_file (pph_file);
2143 read_text_file_p = false;
2146 return read_text_file_p;
2150 /* The initial order of the size of the lexical lookaside table,
2151 which will accomodate as many as half of its slots in use. */
2153 static const unsigned int cpp_lt_order = /* 2 to the power of */ 9;
2156 /* Initialize PTH support. LEXER is the main lexer object used for
2157 pre-processing. */
2159 void
2160 pth_init (cp_lexer *lexer)
2162 pth_state *state;
2163 cpp_callbacks *cb;
2164 cpp_lookaside *table;
2166 timevar_push (TV_PTH_INIT);
2168 gcc_assert (flag_pth);
2170 table = cpp_lt_exchange (parse_in,
2171 cpp_lt_create (cpp_lt_order, flag_pth_debug));
2172 gcc_assert (table == NULL);
2174 memset (&pth_stats, 0, sizeof (pth_stats));
2176 state = pth_get_state ();
2178 /* If not using MD5 signatures, make sure that time stamps given
2179 by stat() are smaller than DIGEST_LEN bytes. FIXME pph, this is
2180 slighly hacky. */
2181 if (!flag_pth_md5)
2183 struct stat tmp;
2184 gcc_assert (sizeof (tmp.st_mtime) < DIGEST_LEN);
2187 /* Set an handler for file change events in libcpp. */
2188 cb = cpp_get_callbacks (parse_in);
2189 state->file_change_prev = cb->file_change;
2190 cb->file_change = pth_file_change;
2191 cb->include = pth_include_handler;
2193 state->lexer = lexer;
2195 /* Make sure that we have not tried to get any tokens yet. */
2196 gcc_assert (VEC_empty (cp_token, lexer->buffer));
2198 /* If we have a valid image for the main input file, populate as
2199 many tokens from its transitive closure as possible. */
2200 state->cur_image = pth_image_lookup (state, main_input_filename, parse_in);
2201 pth_enter_file (parse_in, state->cur_image, NULL, LC_ENTER);
2203 timevar_pop (TV_PTH_INIT);
2207 /* Show statistics on PTH on FILE. If FILE is NULL, use pph_logfile.
2208 LEXER is the lexer we just filled with tokens. This is usually
2209 the same as pth_get_state()->lexer, but it may be NULL if PTH is
2210 not enabled (in cases where we just want stats on pre-processed
2211 files). */
2213 void
2214 pth_print_stats (FILE *file, cp_lexer *lexer)
2216 unsigned i, num_tokens, total_tokens;
2217 pth_state *state;
2218 pth_image *image;
2219 const char *prev_fname;
2220 cp_token *token;
2222 if (file == NULL)
2223 file = pph_logfile;
2225 fprintf (file, "\nPTH statistics\n\n");
2226 fprintf (file, "#included files: %lu\n", pth_stats.included_files);
2227 fprintf (file, "Valid images: %lu\n", pth_stats.valid_images);
2228 fprintf (file, "Token hunks: %lu\n", pth_stats.hunks);
2229 fprintf (file, "Valid hunks: %lu\n", pth_stats.valid_hunks);
2230 fprintf (file, "Invalid hunks: %lu\n", pth_stats.invalid_hunks);
2231 fprintf (file, "Verified hunks: %lu\n", pth_stats.verified_hunks);
2232 fprintf (file, "Verified identifiers: %lu\n", pth_stats.verified_identifiers);
2234 state = pth_get_state ();
2235 fprintf (file, "\n\nPTH image statistics (%u files)\n\n",
2236 VEC_length (pth_image_ptr, state->cache));
2237 for (i = 0; VEC_iterate (pth_image_ptr, state->cache, i, image); i++)
2238 pth_show_image_stats (file, image);
2240 fprintf (file, "\nToken counts per file in #include order:\n");
2241 num_tokens = total_tokens = 0;
2242 prev_fname = NULL;
2243 for (i = 0; VEC_iterate (cp_token, lexer->buffer, i, token); i++)
2245 const char *fname = LOCATION_FILE (token->location);
2247 if (prev_fname == NULL)
2248 prev_fname = fname;
2250 if ((fname
2251 && strcmp (fname, prev_fname) != 0)
2252 || i == VEC_length (cp_token, lexer->buffer) - 1)
2254 fprintf (file, "tokens: %u %s\n", num_tokens, lrealpath (prev_fname));
2255 prev_fname = fname;
2256 total_tokens += num_tokens;
2257 num_tokens = 0;
2260 num_tokens++;
2263 /* The main lexer buffer should have one more token: CPP_EOF. */
2264 if (total_tokens != VEC_length (cp_token, lexer->buffer) - 1)
2265 fprintf (stderr, "*** WARNING: I counted %u, but there are %u\n",
2266 total_tokens, VEC_length (cp_token, lexer->buffer));
2268 fprintf (file, "\n");
2272 /* Save all the header images that have been marked modified from
2273 the incremental state. */
2275 void
2276 pth_finish (void)
2278 /* If PPH is enabled, do not save PTH images to prevent analysis problems
2279 due to lack of location information in PTH images. FIXME pph:
2280 Unneeded after we start saving proper location information. */
2281 if (flag_pph_debug >= 1)
2282 fprintf (stderr, "*** WARNING: Not saving PTH images because PPH "
2283 "is enabled\n");
2284 else
2286 pth_state *state;
2287 pth_image *image;
2288 size_t i;
2290 state = pth_get_state ();
2291 for (i = 0; VEC_iterate (pth_image_ptr, state->cache, i, image); i++)
2292 if (image->save_p)
2293 pth_save_image (image);
2298 static void
2299 pph_log_exposed (cp_parser *parser, const char *end)
2301 if (flag_pph_decls_debug >= 2)
2303 cp_token *pos = cp_lexer_token_position (parser->lexer, false);
2304 fprintf (pph_logfile, "PPH: %s exposed declaration at ", end);
2305 pph_debug_location (pph_logfile, pos->location);
2306 fprintf (pph_logfile, "\n");
2311 /* Allocate the various arrays, maps and sets used to collect ASTs and
2312 their dependencies during parsing. This memory is allocated and
2313 freed for every grammar rule intercepted by pph_start_exposed() and
2314 pph_stop_exposed(). */
2316 static void
2317 pph_allocate_catcher_memory (void)
2319 /* Note. pph_tree_catcher *must* be instantiated to indicate that
2320 we are going to be catching trees during parsing. */
2321 pph_tree_catcher = VEC_alloc (tree, heap, 5);
2322 pph_decl_head_token_cache = pointer_map_create ();
2323 pph_decl_body_token_cache = pointer_map_create ();
2324 pph_decl_deps = XCNEW (struct pph_decl_deps_d);
2325 pph_decl_deps->header = pointer_map_create ();
2326 pph_decl_deps->body = pointer_map_create ();
2327 pph_name_lookups = NULL;
2328 pph_name_lookups_set = pointer_set_create ();
2329 pph_nl_token_map = pointer_map_create ();
2333 /* Free all the memory allocated by pph_allocate_catcher_memory. */
2335 static void
2336 pph_free_catcher_memory (void)
2338 VEC_free (tree, heap, pph_tree_catcher);
2340 pointer_map_destroy (pph_decl_head_token_cache);
2341 pph_decl_head_token_cache = NULL;
2343 pointer_map_destroy (pph_decl_body_token_cache);
2344 pph_decl_body_token_cache = NULL;
2346 pointer_map_destroy (pph_decl_deps->header);
2347 pointer_map_destroy (pph_decl_deps->body);
2348 free (pph_decl_deps);
2349 pph_decl_deps = NULL;
2351 VEC_free (tree, heap, pph_name_lookups);
2353 pointer_set_destroy (pph_name_lookups_set);
2354 pph_name_lookups_set = NULL;
2356 pointer_map_destroy (pph_nl_token_map);
2357 pph_nl_token_map = NULL;
2361 /* Start collecting ASTs and dependencies. */
2363 cp_token *
2364 pph_start_exposed (cp_parser *parser)
2366 if (flag_pph_decls_debug >= 2)
2368 timevar_push (TV_PPH_MANAGE);
2370 if (flag_pph_decls_debug >= 4)
2371 fprintf (pph_logfile, "\n--------------------------------------------------------------------------\n");
2372 pph_log_exposed (parser, "start");
2373 pph_allocate_catcher_memory ();
2374 timevar_pop (TV_PPH_MANAGE);
2376 return parser->lexer->next_token; /* the first token */
2378 else
2379 return NULL;
2382 /* Return the token cache associated with tree node T. */
2384 static VEC(cp_token, heap) *
2385 pph_lookup_head_token_cache_for (tree t)
2387 void **slot = pointer_map_contains (pph_decl_head_token_cache, t);
2388 if (slot)
2389 return ((VEC(cp_token, heap) *) *slot);
2391 return NULL;
2394 static VEC(cp_token, heap) *
2395 pph_lookup_body_token_cache_for (tree t)
2397 void **slot = pointer_map_contains (pph_decl_body_token_cache, t);
2398 if (slot)
2399 return ((VEC(cp_token, heap) *) *slot);
2401 return NULL;
2405 /* Set the token cache associated with tree node T to CACHE. */
2407 static void
2408 pph_set_head_token_cache_for (tree t, VEC(cp_token, heap) *cache)
2410 void **slot = pointer_map_insert (pph_decl_head_token_cache, t);
2411 *slot = (void *) cache;
2414 static void
2415 pph_set_body_token_cache_for (tree t, VEC(cp_token, heap) *cache)
2417 void **slot = pointer_map_insert (pph_decl_body_token_cache, t);
2418 *slot = (void *) cache;
2421 /* Emulate the copying of declarations into the parser cache. Deep
2422 copy all the declarations in V. */
2424 static void
2425 pph_copy_decls_into_cache (VEC(tree, heap) *v)
2427 unsigned i;
2428 static tree t_copy, type_copy, t;
2429 void **slot;
2430 VEC(tree, heap) *ast_cache, *old_pph_tree_catcher, *old_pph_name_lookups;
2431 static struct pointer_map_t *hunk_to_decls_map = NULL;
2432 static htab_t cache_dir = NULL;
2433 const char *fname;
2435 timevar_push (TV_PPH_CACHE_IN);
2437 if (hunk_to_decls_map == NULL)
2438 hunk_to_decls_map = pointer_map_create ();
2440 if (cache_dir == NULL)
2441 cache_dir = htab_create (10, htab_hash_pointer, htab_eq_pointer, 0);
2443 /* We will be copying trees, which will call into the tree catching
2444 routines. Prevent that. */
2445 old_pph_tree_catcher = pph_tree_catcher;
2446 old_pph_name_lookups = pph_name_lookups;
2447 pph_tree_catcher = pph_name_lookups = NULL;
2449 /* Copy every declaration in V into the cache. */
2450 for (i = 0; VEC_iterate (tree, v, i, t); i++)
2452 /* 1- Determine the token hunk H that owns T. We first determine
2453 the PTH image and then which hunk inside that PTH image. For
2454 choosing the hunk within the image, we simulate a second
2455 hash table lookup hashing the location to the token hunk. */
2456 pth_image *image, *hunk;
2457 VEC(cp_token, heap) *head_tokens, *body_tokens;
2458 cp_token *first;
2460 head_tokens = pph_lookup_head_token_cache_for (t);
2461 body_tokens = pph_lookup_body_token_cache_for (t);
2462 if (VEC_empty (cp_token, head_tokens))
2463 continue;
2464 first = VEC_index (cp_token, head_tokens, 0);
2465 fname = LOCATION_FILE (first->location);
2466 slot = htab_find_slot (cache_dir, fname, INSERT);
2467 if (*slot == NULL)
2469 image = XCNEW (pth_image);
2470 *slot = CONST_CAST (char *, fname);
2472 else
2473 image = *((pth_image **) slot);
2475 /* For now, re-do the pth_image_lookup to simulate the lookup of
2476 the hunk within the image. */
2477 slot = htab_find_slot (cache_dir, fname, NO_INSERT);
2478 hunk = *((pth_image **) slot);
2480 /* Insert dummy uses for head_tokens, body_tokens and image. */
2481 if (i > VEC_length (tree, v))
2483 free (head_tokens);
2484 free (body_tokens);
2485 free (image);
2488 /* 2- Find the tree cache associated with HUNK. */
2489 slot = pointer_map_insert (hunk_to_decls_map, hunk);
2490 ast_cache = (VEC(tree, heap) *) *slot;
2492 /* 3- Copy T and its type into the cache associated with HUNK.
2493 If T has a body (a FUNCTION_DECL), copy the body. FIXME pph,
2494 copying ASTs will need new copying code to be implemented,
2495 the current routines do not handle everything that can be
2496 generated by the C++ FE. */
2497 t_copy = copy_decl (t);
2498 if (!type_copy || TREE_TYPE (t))
2499 type_copy = copy_type (TREE_TYPE (t));
2500 if (TREE_CODE (t) == FUNCTION_DECL)
2501 walk_tree (&DECL_SAVED_TREE (t_copy), copy_tree_r, (void *)1, NULL);
2502 VEC_safe_push (tree, heap, ast_cache, t_copy);
2503 *slot = (void *) ast_cache;
2506 PPH_STATS_INCR (cached_decls, VEC_length (tree, v));
2508 /* Restore tree and lookup catchers. */
2509 pph_tree_catcher = old_pph_tree_catcher;
2510 pph_name_lookups = old_pph_name_lookups;
2512 timevar_pop (TV_PPH_CACHE_IN);
2516 /* Emulate the cache actions needed to get a declaration out of the
2517 parser cache and instantiate it into the current compilation context. */
2519 static void
2520 pph_copy_decls_outof_cache (VEC(tree, heap) *v)
2522 unsigned i;
2523 tree t;
2524 static VEC(tree, heap) *compilation_context = NULL;
2525 VEC(tree, heap) *old_pph_tree_catcher, *old_pph_name_lookups;
2527 /* Conceptually, this will be called with a token hunk that contains
2528 all the declarations that we want to instantiate. */
2529 timevar_push (TV_PPH_CACHE_OUT);
2531 /* We will be copying trees, which will call into the tree catching
2532 routines. Prevent that. */
2533 old_pph_tree_catcher = pph_tree_catcher;
2534 old_pph_name_lookups = pph_name_lookups;
2535 pph_tree_catcher = pph_name_lookups = NULL;
2537 /* 1- Verify that the hunk is valid. Traverse all the declarations
2538 checking that none have been tainted. */
2539 for (i = 0; VEC_iterate (tree, v, i, t); i++)
2541 /* If T is not valid, none of its users is valid. */
2542 if (1 || TREE_VISITED (t))
2544 unsigned j;
2545 tree r;
2546 for (j = 0; VEC_iterate (tree, v, j, r); j++)
2547 TREE_VISITED (r) = TREE_VISITED (r);
2551 /* 2- Copy all the trees in the hunk to the current compilation context. */
2552 for (i = 0; VEC_iterate (tree, v, i, t); i++)
2554 static tree t_copy, type_copy;
2556 t_copy = copy_decl (t);
2557 if (!type_copy || TREE_TYPE (t))
2558 type_copy = copy_type (TREE_TYPE (t));
2559 if (TREE_CODE (t) == FUNCTION_DECL)
2560 walk_tree (&DECL_SAVED_TREE (t_copy), copy_tree_r, (void *)1, NULL);
2562 /* Emulate restoration into compilation context. FIXME pph, this is
2563 missing the name lookups that may be required. Estimate this
2564 separately from the number of name lookup operations and the
2565 time spent doing name lookups. */
2566 VEC_safe_push (tree, heap, compilation_context, t_copy);
2569 PPH_STATS_INCR (restored_decls, VEC_length (tree, v));
2571 /* Restore tree and lookup catchers. */
2572 pph_tree_catcher = old_pph_tree_catcher;
2573 pph_name_lookups = old_pph_name_lookups;
2575 timevar_pop (TV_PPH_CACHE_OUT);
2578 void
2579 pph_stop_exposed (cp_parser *parser, cp_token *first_token)
2581 if (flag_pph_decls_debug >= 2 && !VEC_empty (tree, pph_tree_catcher))
2583 cp_token *last_token;
2585 timevar_push (TV_PPH_MANAGE);
2587 last_token = parser->lexer->next_token;
2588 pph_print_trees_tokens (pph_tree_catcher, first_token, last_token);
2589 pph_copy_decls_into_cache (pph_tree_catcher);
2590 pph_copy_decls_outof_cache (pph_tree_catcher);
2591 PPH_STATS_INCR (cached_refs, VEC_length(tree, pph_name_lookups));
2592 pph_free_catcher_memory ();
2593 if (flag_pph_decls_debug >= 4)
2594 pph_log_exposed (parser, "stop");
2596 timevar_pop (TV_PPH_MANAGE);
2601 /* PPH printing help. */
2603 static void
2604 pph_debug_tree (tree t, bool body)
2606 if (t == NULL)
2608 fprintf (pph_logfile, "nulldecl");
2609 return;
2612 if (!DECL_P (t))
2614 fprintf (pph_logfile, "__%s__", tree_code_name[TREE_CODE (t)]);
2615 return;
2618 if (flag_pph_decls >= 2)
2619 fprintf (pph_logfile, "%s ", tree_code_name[TREE_CODE (t)]);
2620 fprintf (pph_logfile, "%d", (DECL_UID (t) << 1) + body);
2621 if (flag_pph_decls >= 1)
2622 fprintf (pph_logfile, " '%s'", get_name (t));
2623 if (flag_pph_decls >= 3)
2625 fprintf (pph_logfile, " ");
2626 pph_debug_loc_of_tree (pph_logfile, t);
2627 if (flag_pph_decls >= 4)
2628 fprintf (pph_logfile, " @%p", (void *) t);
2632 static void
2633 pph_debug_type (tree t, bool body)
2635 tree t_decl;
2636 if (t == NULL)
2638 fprintf (pph_logfile, "nulltype");
2639 return;
2641 t_decl = get_type_decl (t);
2642 if (t_decl == NULL)
2643 fprintf (pph_logfile, "nameless");
2644 else
2645 pph_debug_tree (t_decl, body);
2648 /* Return true if tree T has been caught already. */
2650 static bool
2651 pph_tree_caught_p (tree t)
2653 return (pph_lookup_head_token_cache_for (t) != NULL);
2656 /* Collect the tokens needed for the head of DECL.
2657 This assumes that the current token is positioned right after
2658 the end of the declarator expression for DECL (i.e., it should
2659 be called from grokdeclarator). */
2661 static VEC(cp_token, heap) *
2662 pph_catch_head_tokens_for (tree t)
2664 cp_token *tok, *last, *first;
2665 cp_lexer *lexer;
2666 VEC(cp_token, heap) *tokens;
2668 gcc_assert (t != error_mark_node);
2670 tokens = pph_lookup_head_token_cache_for (t);
2671 if (tokens)
2673 fprintf (stderr, "*** ");
2674 pph_debug_location (stderr, input_location);
2675 fprintf (stderr, ": Tried to catch head tokens more than once for: ");
2676 print_generic_stmt (stderr, t, 0);
2677 gcc_unreachable ();
2680 lexer = the_parser->lexer;
2682 /* Look for the tokens backwards until the first brace or semicolon. */
2683 first = last = lexer->next_token;
2684 for (tok = last - 1; tok >= VEC_address (cp_token, lexer->buffer); tok--)
2686 if (tok->type == CPP_OPEN_BRACE
2687 || tok->type == CPP_CLOSE_BRACE
2688 || tok->type == CPP_SEMICOLON)
2689 break;
2691 first = tok;
2694 /* Now include any trailing semicolon. */
2695 if (last->type == CPP_SEMICOLON)
2696 last++;
2698 /* Add all the tokens in [FIRST, LAST) to TOKENS. */
2699 for (tok = first; tok != last; tok++)
2700 VEC_safe_push (cp_token, heap, tokens, tok);
2702 pph_set_head_token_cache_for (t, tokens);
2704 return tokens;
2708 /* Collect the tokens needed for the body of DECL.
2709 This assumes that the current token is positioned right after
2710 the end of the declarator expression for DECL (i.e., it should
2711 be called from grokdeclarator). */
2713 static VEC(cp_token, heap) *
2714 pph_catch_body_tokens_for (tree t)
2716 cp_token *tok, *last, *first;
2717 cp_lexer *lexer;
2718 VEC(cp_token, heap) *tokens;
2720 gcc_assert (t != error_mark_node);
2722 tokens = pph_lookup_body_token_cache_for (t);
2723 if (tokens)
2725 fprintf (stderr, "*** ");
2726 pph_debug_location (stderr, input_location);
2727 fprintf (stderr, ": Tried to catch body tokens more than once for: ");
2728 print_generic_stmt (stderr, t, 0);
2729 gcc_unreachable ();
2732 lexer = the_parser->lexer;
2734 /* Look for the tokens forwards until the closing brace or semicolon. */
2735 first = last = lexer->next_token;
2736 tok = first;
2737 if (tok->type == CPP_EQ || tok->type == CPP_OPEN_PAREN)
2739 /* Skip a variable-like definition. Find the semicolon. */
2740 /* FIXME pph - This code changes with C++0x. */
2741 for (; tok <= VEC_last (cp_token, lexer->buffer); tok++)
2742 if (tok->type == CPP_SEMICOLON)
2743 break;
2744 last = tok;
2746 else if (tok->type == CPP_OPEN_BRACE || tok->type == CPP_COLON)
2748 /* Skip a class-like or function-like definition.
2749 Skip to a left brace, then skip to the matching right brace. */
2750 /* FIXME pph - This code changes with C++0x. */
2751 int nesting = 0;
2752 for (; tok <= VEC_last (cp_token, lexer->buffer); tok++)
2753 if (tok->type == CPP_OPEN_BRACE)
2754 nesting++;
2755 else if (tok->type == CPP_CLOSE_BRACE)
2757 if ( nesting <= 1)
2758 break;
2759 else
2760 nesting--;
2762 last = tok;
2764 else
2765 return NULL; /* no body */
2767 /* Add all the tokens in [FIRST, LAST) to TOKENS. */
2768 for (tok = first; tok <= last; tok++)
2769 VEC_safe_push (cp_token, heap, tokens, tok);
2771 pph_set_body_token_cache_for (t, tokens);
2773 return tokens;
2777 /* Return the dependencies for tree node T. If HEADER_P is true, it
2778 returns the dependencies for the header of T's declaration.
2779 Otherwise, it returns dependencies for T's body. */
2781 static VEC(tree,gc) *
2782 pph_lookup_dependencies_for (tree t, bool header_p)
2784 struct pointer_map_t *map;
2785 void **slot;
2787 map = (header_p) ? pph_decl_deps->header : pph_decl_deps->body;
2788 slot = pointer_map_contains (map, t);
2789 if (slot)
2790 return ((VEC(tree,gc) *) *slot);
2792 return NULL;
2796 /* Set the dependencies for tree node T to DEPS. If HEADER_P is true,
2797 DEPS are the dependencies for T's header. Otherwise, DEPS are the
2798 dependencies for T's body. */
2800 static void
2801 pph_set_dependencies_for (tree t, VEC(tree,gc) *deps, bool header_p)
2803 void **slot;
2804 struct pointer_map_t *map;
2806 map = (header_p) ? pph_decl_deps->header : pph_decl_deps->body;
2807 slot = pointer_map_insert (map, t);
2808 *slot = (void *) deps;
2811 #define PPH_ARTIFICIAL(t) \
2812 (DECL_ARTIFICIAL (t) && !DECL_IMPLICIT_TYPEDEF_P (t))
2814 static bool
2815 is_namespace (tree container)
2817 enum tree_code code;
2819 if (container == NULL)
2820 return true;
2822 code = TREE_CODE (container);
2823 if (code == NAMESPACE_DECL)
2824 return true;
2826 return false;
2829 /* Find the exposed declaration containing a symbol lookup. */
2831 static tree
2832 pph_null_exposed (const char *reason)
2834 if (flag_pph_decls_debug >= 3)
2835 fprintf (pph_logfile, "%s\n", reason);
2836 return NULL;
2839 static tree
2840 pph_live_exposed (tree t, bool body)
2842 if (PPH_ARTIFICIAL (t))
2843 return pph_null_exposed ("Artificial symbols are not exposed.");
2845 if (flag_pph_decls_debug >= 3)
2847 if (t == NULL)
2848 fprintf (pph_logfile, "(null)");
2849 else
2850 pph_debug_tree (t, body);
2851 fprintf (pph_logfile, "\n");
2853 return t;
2856 static tree
2857 pph_find_exposed_for (tree t, bool *body)
2859 tree container;
2860 enum tree_code code, t_code;
2861 bool in_class;
2862 *body = false; /* By default, we only depend on heads. */
2863 for ( ; ; t = container, *body = true)
2865 reclassify:
2866 if (t == NULL)
2868 PPH_STATS_INCR (bad_lookups, 1);
2869 return pph_null_exposed ("NULLOID"); /* FIXME pph */
2871 if (flag_pph_decls_debug >= 3)
2873 fprintf (pph_logfile, " exposed for ");
2874 pph_debug_tree (t, false);
2875 fprintf (pph_logfile, " is ");
2877 code = TREE_CODE (t);
2878 switch (code)
2880 /* Types common to C and C++. */
2881 case ARRAY_TYPE:
2882 case BOOLEAN_TYPE:
2883 case COMPLEX_TYPE:
2884 case ENUMERAL_TYPE:
2885 case FIXED_POINT_TYPE:
2886 case FUNCTION_TYPE:
2887 case INTEGER_TYPE:
2888 case LANG_TYPE:
2889 case METHOD_TYPE:
2890 case OFFSET_TYPE:
2891 case POINTER_TYPE:
2892 case QUAL_UNION_TYPE:
2893 case REAL_TYPE:
2894 case RECORD_TYPE:
2895 case REFERENCE_TYPE:
2896 case UNION_TYPE:
2897 case VECTOR_TYPE:
2898 case VOID_TYPE:
2899 /* C++-specific types. */
2900 case BOUND_TEMPLATE_TEMPLATE_PARM:
2901 case TEMPLATE_TEMPLATE_PARM:
2902 case TEMPLATE_TYPE_PARM:
2903 case TYPENAME_TYPE:
2904 case TYPEOF_TYPE:
2905 case UNBOUND_CLASS_TEMPLATE:
2906 case TYPE_ARGUMENT_PACK:
2907 case TYPE_PACK_EXPANSION:
2908 case DECLTYPE_TYPE:
2910 if (TYPE_NAME (t) == NULL)
2911 return pph_null_exposed ("Anonymous Type");
2912 else
2913 t = TYPE_NAME (t);
2914 /* FALLTHRU */
2917 case TYPE_DECL:
2919 container = DECL_CONTEXT (t);
2920 in_class = container && CLASS_TYPE_P (container);
2921 t_code = TREE_CODE (TREE_TYPE (t));
2922 /* FIXME pph: Why DECL_TEMPLATE_TEMPLATE_PARM_P does not apply
2923 here? It is a template template parameter, but the tree code
2924 is inconsistent. */
2925 if (DECL_TEMPLATE_PARM_P (t)
2926 || t_code == TEMPLATE_TEMPLATE_PARM
2927 || t_code == BOUND_TEMPLATE_TEMPLATE_PARM)
2928 return pph_null_exposed ("TMPLPARM");
2930 if (is_namespace (container))
2931 return pph_live_exposed (t, *body);
2932 break;
2935 case VAR_DECL:
2937 /* If var is lazy, depend on its body, not its head. */
2938 tree enclass = DECL_CONTEXT (t);
2939 bool in_class = enclass && CLASS_TYPE_P (enclass);
2940 bool defined = DECL_INITIAL (t) != NULL;
2941 /* FIXME pph: DECL_INITIALIZED_P (t) */
2942 if (defined && (in_class || !DECL_THIS_EXTERN (t))
2943 && decl_constant_var_p (t))
2944 *body = true;
2946 container = DECL_CONTEXT (t);
2947 in_class = container && CLASS_TYPE_P (container);
2948 if (in_class && DECL_THIS_STATIC (t))
2949 container = TYPE_CONTEXT (container);
2950 if (is_namespace (container))
2951 return pph_live_exposed (t, *body);
2952 break;
2955 case FUNCTION_DECL:
2957 /* If function is lazy, depend on body. */
2958 bool defined = DECL_INITIAL (t) != NULL;
2959 if (defined && (DECL_DECLARED_INLINE_P (t)
2960 || DECL_USE_TEMPLATE (t) != 2))
2961 *body = true;
2963 container = DECL_CONTEXT (t);
2964 in_class = container && CLASS_TYPE_P (container);
2965 if (in_class)
2966 container = TYPE_CONTEXT (container);
2967 if (is_namespace (container))
2968 return pph_live_exposed (t, *body);;
2969 break;
2972 case TEMPLATE_DECL:
2974 int generic = DECL_USE_TEMPLATE (t);
2975 if (generic != 2)
2977 t = DECL_TEMPLATE_RESULT (t);
2978 if (flag_pph_decls_debug >= 3)
2979 fprintf (pph_logfile, "template redirected\n");
2980 goto reclassify;
2984 case SCOPE_REF:
2985 return pph_null_exposed ("SCOPE_REF"); /* FIXME pph */
2987 case OVERLOAD:
2988 return pph_null_exposed ("OVERLOAD"); /* FIXME pph */
2990 case BASELINK:
2991 container = BASELINK_BINFO (t);
2992 break;
2994 case TREE_BINFO:
2995 container = BINFO_TYPE (t);
2996 break;
2998 case TREE_LIST:
2999 t = TREE_VALUE (t);
3000 /* Fallthru */
3002 default:
3004 if (t == NULL)
3006 PPH_STATS_INCR (bad_lookups, 1);
3007 return pph_null_exposed ("NULLOID"); /* FIXME pph */
3009 else if (!DECL_P (t))
3011 PPH_STATS_INCR (bad_lookups, 1);
3012 return pph_null_exposed ("BOZOID"); /* FIXME pph */
3013 /*FIXME pph:
3014 fatal_error ("Expecting a *_decl node. Got %s",
3015 tree_code_name[TREE_CODE (t)]);
3019 container = DECL_CONTEXT (t);
3020 in_class = container && CLASS_TYPE_P (container);
3021 if (is_namespace (container))
3022 return pph_null_exposed ("UNKNOWN");
3023 break;
3026 if (flag_pph_decls_debug >= 3)
3028 pph_debug_tree (container, *body);
3029 fprintf (pph_logfile, "\n");
3035 /* Collect the AST nodes that node T depends on. HEADER_P is true if
3036 we should collect ASTs from T's header. Otherwise, we collect
3037 ASTs from T's body. */
3039 static VEC(tree,gc) *
3040 pph_catch_dependencies_for (tree t, bool header_p)
3042 VEC(cp_token, heap) *tokens;
3043 unsigned i;
3044 cp_token *tok;
3045 VEC(tree,gc) *deps;
3047 tokens = (header_p)
3048 ? pph_lookup_head_token_cache_for (t)
3049 : pph_lookup_body_token_cache_for (t);
3051 if (tokens == NULL)
3052 tokens = (header_p)
3053 ? pph_catch_head_tokens_for (t)
3054 : pph_catch_body_tokens_for (t);
3056 deps = pph_lookup_dependencies_for (t, header_p);
3058 for (i = 0; VEC_iterate (cp_token, tokens, i, tok); i++)
3059 if (tok->type == CPP_NAME)
3060 VEC_safe_push (tree, gc, deps, tok->u.value);
3062 pph_set_dependencies_for (t, deps, header_p);
3064 return deps;
3068 /* Intercept tree node T by storing it in pph_tree_catcher and collecting
3069 the tokens used in its instantiation. */
3071 void
3072 pph_catch_tree (tree t)
3074 /* Only collect trees if the parser instantiated pph_tree_catcher
3075 and we are currently parsing from the main lexer. */
3076 if (pph_tree_catcher && the_parser->lexer->buffer && !pph_tree_caught_p (t))
3078 timevar_push (TV_PPH_MANAGE);
3080 VEC_safe_push (tree, heap, pph_tree_catcher, t);
3081 pph_catch_head_tokens_for (t);
3082 pph_catch_body_tokens_for (t);
3083 pph_catch_dependencies_for (t, true);
3084 pph_catch_dependencies_for (t, false);
3086 timevar_pop (TV_PPH_MANAGE);
3091 /* Retract a caught tree. */
3093 void
3094 pph_uncatch_tree (tree t)
3096 /* Only uncollect trees if the parser instantiated pph_tree_catcher
3097 and we are currently parsing from the main lexer. */
3098 if (pph_tree_catcher && the_parser->lexer->buffer)
3100 int i;
3101 tree u;
3103 timevar_push (TV_PPH_MANAGE);
3105 /* Find the index; if present, remove it. */
3106 for (i = 0; VEC_iterate (tree, pph_tree_catcher, i, u); i++)
3108 if (u == t)
3110 VEC_ordered_remove (tree, pph_tree_catcher, i);
3111 break;
3115 timevar_pop (TV_PPH_MANAGE);
3120 /* Given a set of tokens TOKENS, return the symbols from pph_name_lookups
3121 that occur in TOKENS. The returned vector is, then, the set of all
3122 symbols that were resolved via name lookups during parsing. This set
3123 is a subset of all the CPP_NAME tokens in TOKENS. */
3125 static void
3126 pph_locate_name_lookups_in (VEC(cp_token, heap) *tokens,
3127 VEC(tree,gc) **heads_found,
3128 VEC(tree,gc) **bodies_found)
3130 unsigned i;
3131 tree t;
3132 cp_token *first, *last;
3134 *heads_found = NULL;
3135 *bodies_found = NULL;
3137 if (tokens == NULL || VEC_empty (cp_token, tokens))
3138 return;
3140 first = VEC_index (cp_token, tokens, 0);
3141 last = VEC_last (cp_token, tokens);
3143 for (i = 0; VEC_iterate (tree, pph_name_lookups, i, t); i++)
3145 unsigned j;
3146 cp_token *tok;
3147 VEC(cp_token, heap) *lookup_locations;
3148 void **slot;
3149 bool pushed = false;
3151 slot = pointer_map_contains (pph_nl_token_map, t);
3152 gcc_assert (slot && *slot);
3153 lookup_locations = (VEC(cp_token, heap) *) *slot;
3154 for (j = 0; VEC_iterate (cp_token, lookup_locations, j, tok); j++)
3156 if (tok->location >= first->location
3157 && tok->location <= last->location)
3159 if (!pushed)
3161 bool body;
3162 tree exposed = pph_find_exposed_for (t, &body);
3163 if (exposed)
3165 if (body)
3166 VEC_safe_push (tree, gc, *bodies_found, exposed);
3167 else
3168 VEC_safe_push (tree, gc, *heads_found, exposed);
3169 pushed = true;
3173 /* Avoid double-counting lookups by removing the lookup
3174 location after a class member declaration has found it.
3175 To make that work, we must remove all redundant entries. */
3176 if (flag_pph_decls_debug >= 4)
3178 fprintf (pph_logfile, " lookup in %p for ",
3179 (void*)lookup_locations);
3180 pph_debug_tree (t, false);
3181 fprintf (pph_logfile, " found at ");
3182 pph_debug_location (pph_logfile, tok->location);
3183 fprintf (pph_logfile, "\n");
3184 fprintf (pph_logfile, " vector length from %d",
3185 VEC_length (cp_token, lookup_locations));
3188 /* This code is slow, but VEC won't let me null entires. */
3189 VEC_ordered_remove (cp_token, lookup_locations, j);
3190 /* We have just shifted down all later entries,
3191 and need to counteract the upcoming index increment. */
3192 j--;
3193 if (flag_pph_decls_debug >= 4)
3195 fprintf (pph_logfile, " to %d\n",
3196 VEC_length (cp_token, lookup_locations));
3204 /* Print all the trees in V and the tokens in the token range
3205 [TOK1, TOK2). */
3207 static VEC(cp_token, heap) *
3208 pph_print_copy_tokens (cp_token *tok1, cp_token *tok2)
3210 cp_token *tok;
3211 VEC(cp_token, heap) *vtok;
3213 /* If TOK2 is CPP_EOF, it will have the address of eof_token, which
3214 will make the loop below go off the deep end. Detect this and
3215 make TOK2 the last token in the lexer buffer instead. */
3216 if (tok2 == &eof_token)
3217 tok2 = VEC_last (cp_token, the_parser->lexer->buffer);
3219 vtok = NULL;
3220 for (tok = tok1; tok != tok2; tok++)
3221 VEC_safe_push (cp_token, heap, vtok, tok);
3223 return vtok;
3226 static void
3227 pph_print_token_range (VEC(tree,heap) *v, VEC(cp_token, heap) *vtok)
3229 unsigned i;
3230 tree t;
3232 if (flag_pph_decls_debug >= 4)
3234 fprintf (pph_logfile, "PPH: hunk location ");
3235 pph_debug_location (pph_logfile, VEC_index (cp_token, vtok, 0)->location);
3236 fprintf (pph_logfile, " to ");
3237 pph_debug_location (pph_logfile, VEC_last (cp_token, vtok)->location);
3238 fprintf (pph_logfile, "\n");
3239 fprintf (pph_logfile, "PPH: hunk tokens ");
3240 cp_lexer_dump_tokens (stderr, (VEC(cp_token, gc) *)vtok, NULL, 0, NULL);
3241 fprintf (pph_logfile, "PPH: hunk ASTs:\n");
3242 for (i = 0; VEC_iterate (tree, v, i, t); i++)
3244 pph_debug_tree (t, true);
3245 /* FIXME pph: this may not be right; we may not care. */
3246 print_generic_stmt (stderr, t, 0);
3248 fprintf (pph_logfile, "PPH: hunk decls:\n");
3252 static void
3253 pph_print_dependence (bool user_body, bool used_body,
3254 tree t, tree d)
3256 static bool prior_user_body = false;
3257 static bool prior_used_body = false;
3258 static tree prior_t = NULL;
3259 static tree prior_d = NULL;
3260 if (flag_pph_decls_debug >= 2)
3262 fprintf (pph_logfile, " pd_base ");
3263 pph_debug_tree (t, user_body);
3264 fprintf (pph_logfile, " on ");
3265 pph_debug_tree (d, used_body);
3266 fprintf (pph_logfile, "\n");
3268 if (t && d && DECL_P (t) && DECL_P (d) && (t != d || user_body != used_body))
3270 if (PPH_ARTIFICIAL (t))
3272 /* Okay, find the real symbol this articial one belongs to. */
3273 d = pph_find_exposed_for (d, &used_body);
3274 if (d == NULL)
3275 return;
3276 used_body = true;
3278 if (user_body != prior_user_body
3279 || used_body != prior_used_body
3280 || t != prior_t
3281 || d != prior_d)
3283 fprintf (pph_logfile, "depend ");
3284 pph_debug_tree (t, user_body);
3285 fprintf (pph_logfile, " uses ");
3286 pph_debug_tree (d, used_body);
3287 fprintf (pph_logfile, "\n");
3288 prior_user_body = user_body;
3289 prior_used_body = used_body;
3290 prior_t = t;
3291 prior_d = d;
3296 static void
3297 pph_print_depend_template (tree tmpl_info, tree t)
3299 tree tmpl_decl;
3300 tree tmpl_ptrn;
3301 if (flag_pph_decls_debug >= 2)
3303 fprintf (pph_logfile, " pd_template ");
3304 pph_debug_tree (t, true);
3305 fprintf (pph_logfile, " %p", (void*)tmpl_info);
3306 fprintf (pph_logfile, "\n");
3308 tmpl_decl = TI_TEMPLATE (tmpl_info);
3309 if (TREE_CODE (tmpl_decl) == OVERLOAD)
3310 tmpl_decl = OVL_CURRENT (tmpl_decl);
3311 tmpl_ptrn = DECL_TEMPLATE_RESULT (tmpl_decl);
3312 if (tmpl_ptrn && t != tmpl_ptrn)
3314 /* This is a template, but not the pattern. */
3315 pph_print_dependence (true, true, t, tmpl_ptrn);
3319 /* Print the dependence of a head of declaration
3320 on the body of a type that the head uses directly.
3321 If either of these is not exposed,
3322 find the body of the exposed declaration that contains it. */
3324 static void
3325 pph_print_depend_decl (tree user, tree used)
3327 if (flag_pph_decls_debug >= 2)
3329 fprintf (pph_logfile, " pd_decl ");
3330 pph_debug_tree (user, false);
3331 fprintf (pph_logfile, " on ");
3332 pph_debug_tree (used, false);
3333 fprintf (pph_logfile, "\n");
3335 if (user != NULL)
3337 if (used != NULL)
3339 bool body;
3340 tree exp_for_user = pph_find_exposed_for (user, &body);
3341 tree exp_for_used = pph_find_exposed_for (used, &body);
3342 if (exp_for_user && exp_for_used && exp_for_user != exp_for_used)
3343 pph_print_dependence (exp_for_user != user, true,
3344 exp_for_user, exp_for_used);
3349 static void
3350 pph_print_depend_type (tree decl, tree type)
3352 tree type_decl;
3353 if (flag_pph_decls_debug >= 2)
3355 fprintf (pph_logfile, " pd_type ");
3356 pph_debug_tree (decl, false);
3357 fprintf (pph_logfile, " on ");
3358 pph_debug_type (type, false);
3359 fprintf (pph_logfile, "\n");
3361 if (type != NULL)
3363 type_decl = get_type_decl (type);
3364 pph_print_depend_decl (decl, type_decl);
3368 static void
3369 pph_print_depend_type_type (tree t)
3371 tree t_type;
3372 tree field;
3374 if (flag_pph_decls_debug >= 2)
3376 fprintf (pph_logfile, " depending on typedecl type ");
3377 pph_debug_tree (t, false);
3378 fprintf (pph_logfile, "\n");
3381 t_type = TREE_TYPE (t);
3382 field = TYPE_FIELDS (t_type);
3383 for (; field; field = TREE_CHAIN(field))
3385 if (flag_pph_decls_debug >= 2)
3387 fprintf (pph_logfile, " field ");
3388 pph_debug_tree (field, false);
3390 if (TREE_CODE (field) == FIELD_DECL)
3392 tree f_type = TREE_TYPE (field);
3393 if (flag_pph_decls_debug >= 2)
3395 fprintf (pph_logfile, " of type ");
3396 pph_debug_type (f_type, false);
3397 if (DECL_FIELD_IS_BASE (field))
3398 fprintf (pph_logfile, " is a base field!!\n");
3399 else
3400 fprintf (pph_logfile, " is a plain field\n");
3402 pph_print_depend_type (t, f_type);
3404 else if (TREE_CODE (field) == TYPE_DECL)
3406 tree f_type = TREE_TYPE (field);
3407 if (flag_pph_decls_debug >= 2)
3409 fprintf (pph_logfile, " of type ");
3410 pph_debug_type (f_type, false);
3411 fprintf (pph_logfile, " is a type field\n");
3413 pph_print_depend_type (t, f_type);
3417 if (flag_pph_decls_debug >= 2)
3419 fprintf (pph_logfile, " end of fields\n");
3423 static void
3424 pph_print_depend_func_type (tree t)
3426 /* We must print a dependence of the head of the function
3427 on the body of the types of its signature. */
3429 tree args;
3430 tree func_type;
3432 if (flag_pph_decls_debug >= 2)
3434 fprintf (pph_logfile, " depending on function type ");
3435 pph_debug_tree (t, false);
3436 fprintf (pph_logfile, "\n");
3439 func_type = TREE_TYPE (t);
3440 pph_print_depend_type (t, TREE_TYPE (func_type)); /* return type */
3441 for (args = TYPE_ARG_TYPES (func_type); args; args = TREE_CHAIN (args))
3442 pph_print_depend_type (t, TREE_VALUE (args)); /* parameter */
3444 if (DECL_VIRTUAL_P (t))
3446 tree ctx_type = DECL_CONTEXT (t);
3447 tree ctx_decl = get_type_decl (ctx_type);
3448 /* Virtual functions depend on containing class's body.*/
3449 pph_print_depend_type (t, ctx_type);
3450 /* The virtual class's body also depends on the function
3451 for construction of the vtable. */
3452 pph_print_dependence (true, true, ctx_decl, t);
3456 static void
3457 pph_print_depend_var_type (tree t)
3459 if (flag_pph_decls_debug >= 2)
3461 fprintf (pph_logfile, " depending on var/field type ");
3462 pph_debug_tree (t, false);
3463 fprintf (pph_logfile, "\n");
3466 pph_print_depend_type (t, TREE_TYPE (t));
3469 enum decl_exposure { HIDDEN, EXPOSED, NEEDED };
3471 static enum decl_exposure
3472 pph_get_decl_exposure (tree t)
3474 tree container;
3475 tree type;
3476 tree tmpl_info;
3477 bool defined = false;
3478 bool inlined = false;
3479 bool needed = false;
3480 int generic = 0;
3481 enum tree_code code = TREE_CODE (t);
3483 if (flag_pph_decls_debug >= 2)
3485 fprintf (pph_logfile, " get_exposure for ");
3486 pph_debug_tree (t, false);
3487 fprintf (pph_logfile, "\n");
3490 /* For DECL_USE_TEMPLATE and CLASSTYPE_USE_TEMPLATE,
3491 1=implicit instantiation
3492 2=partial or explicit specialization, e.g.:
3493 template <> int min<int> (int, int),
3494 3=explicit instantiation, e.g.:
3495 template int min<int> (int, int);
3498 if (code == TYPE_DECL)
3500 pph_print_depend_type_type (t);
3502 container = DECL_CONTEXT (t);
3503 if (!is_namespace (container))
3504 return HIDDEN;
3505 type = TREE_TYPE (t);
3506 defined = COMPLETE_TYPE_P (type);
3508 /* FIXME pph: Why DECL_TEMPLATE_TEMPLATE_PARM_P does not apply
3509 here? It is a template template parameter, but the tree code
3510 is inconsistent. */
3511 if (DECL_TEMPLATE_PARM_P (t)
3512 || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
3513 || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
3514 return HIDDEN;
3515 if (CLASS_TYPE_P (t))
3517 tmpl_info = CLASSTYPE_TEMPLATE_INFO (type);
3518 generic = CLASSTYPE_USE_TEMPLATE (type);
3520 else
3522 tmpl_info = NULL;
3523 generic = 0;
3525 if (generic == 1)
3526 return HIDDEN;
3527 if (tmpl_info != NULL)
3529 pph_print_depend_template (tmpl_info, t);
3530 needed = defined && generic == 3;
3532 else
3534 needed = false;
3537 else if (code == VAR_DECL)
3539 tree enclass = DECL_CONTEXT (t);
3540 bool in_class = enclass && CLASS_TYPE_P (enclass);
3541 /* If the VAR_DECL is in a class, it must be a static member. */
3542 container = enclass;
3543 if (in_class)
3544 container = TYPE_CONTEXT (enclass);
3546 pph_print_depend_var_type (t);
3548 if (!is_namespace (container))
3549 return HIDDEN;
3550 defined = DECL_INITIAL (t) != NULL /* FIXME pph: DECL_INITIALIZED_P (t) */;
3551 type = TREE_TYPE (t);
3552 needed = !((!defined && (in_class || DECL_THIS_EXTERN (t)))
3553 || decl_constant_var_p (t));
3554 if (in_class)
3556 tmpl_info = DECL_TEMPLATE_INFO (t);
3557 generic = DECL_USE_TEMPLATE (t);
3558 if (generic == 1)
3559 return HIDDEN;
3561 else
3563 tmpl_info = NULL;
3564 generic = 0;
3566 if (tmpl_info != NULL)
3568 pph_print_depend_template (tmpl_info, t);
3569 needed = needed && generic == 3;
3572 else if (code == FUNCTION_DECL)
3574 if (flag_pph_decls_debug >= 2)
3576 fprintf (pph_logfile, " depending on function ");
3577 pph_debug_tree (t, false);
3578 fprintf (pph_logfile, "\n");
3581 container = DECL_CONTEXT (t);
3582 if (container && CLASS_TYPE_P (container))
3583 container = TYPE_CONTEXT (DECL_CONTEXT (t));
3585 pph_print_depend_func_type (t);
3587 if (!is_namespace (container))
3588 return HIDDEN;
3589 inlined = DECL_DECLARED_INLINE_P (t);
3590 defined = DECL_INITIAL (t) != NULL;
3591 tmpl_info = DECL_TEMPLATE_INFO (t);
3592 generic = DECL_USE_TEMPLATE (t);
3593 if (tmpl_info != NULL)
3595 if (generic == 2)
3596 needed = defined && !inlined;
3597 else
3599 pph_print_depend_template (tmpl_info, t);
3600 needed = defined && !inlined && generic == 3;
3603 else
3605 needed = defined && !inlined;
3608 else
3610 gcc_assert (code < MAX_TREE_CODES);
3611 return HIDDEN;
3614 if (needed)
3615 return NEEDED;
3616 else
3617 return EXPOSED;
3620 static void
3621 pph_print_dependences (bool user_body, bool used_body,
3622 tree t, VEC(tree,gc) *deps)
3624 unsigned j;
3625 tree d;
3626 for (j = 0; VEC_iterate (tree, deps, j, d); j++)
3627 pph_print_dependence (user_body, used_body, t, d);
3630 /* Print the head of declaration T and its dependencies. N_HEAD_TOKENS
3631 is the number of tokens taken by T's head. N_HEAD_ITOKENS is the
3632 number of invisible tokens.
3634 HEAD_TOKENS is the array of tokens in the head (note that the
3635 length of this array may be different than N_HEAD_TOKENS, due to
3636 adjustments made by the caller).
3638 If CONTAINER is set, then T is a member of it. */
3640 static void
3641 pph_print_declaration_head (tree t, bool artificial, tree container,
3642 unsigned n_head_tokens, unsigned n_head_invis,
3643 VEC(cp_token, heap) *head_tokens)
3645 VEC(tree,gc) *sym_head_deps, *sym_body_deps;
3646 enum tree_code code = TREE_CODE (t);
3648 fprintf (pph_logfile, "declaration ");
3649 pph_debug_tree (t, false);
3651 fprintf (pph_logfile, " htok %u,%u", n_head_tokens, n_head_invis);
3653 /*FIXME pph: We want to get rid of most artificial tokens;
3654 this is temporary to find them. */
3655 if (artificial)
3656 fprintf (pph_logfile, " artificial");
3658 if (container)
3660 fprintf (pph_logfile, " mbrof ");
3661 pph_debug_tree (get_type_decl (container), true);
3664 fprintf (pph_logfile, "\n");
3666 /* Template instances should depend on their pattern body. */
3667 if (artificial)
3669 if (code == TYPE_DECL)
3671 tree t_type = TREE_TYPE (t);
3672 if (CLASS_TYPE_P (t_type))
3674 tree tmpl_info = CLASSTYPE_TEMPLATE_INFO (t_type);
3675 if (tmpl_info != NULL)
3676 pph_print_depend_template (tmpl_info, t);
3679 else if (code == VAR_DECL || code == FUNCTION_DECL)
3681 tree tmpl_info;
3682 tmpl_info = (DECL_LANG_SPECIFIC (t)) ? DECL_TEMPLATE_INFO (t) : NULL;
3683 if (tmpl_info != NULL)
3684 pph_print_depend_template (tmpl_info, t);
3687 else
3689 /* From the name dependencies, determine symbol dependencies
3690 by correlating the location of the looked-up symbols with
3691 the tokens in HEAD_TOKENS and BODY_TOKENS. */
3692 if (flag_pph_decls_debug >= 2)
3693 fprintf (pph_logfile, " begin normal dependences\n");
3694 pph_locate_name_lookups_in (head_tokens, &sym_head_deps, &sym_body_deps);
3695 pph_print_dependences (false, false, t, sym_head_deps);
3696 pph_print_dependences (true, false, t, sym_body_deps);
3697 if (flag_pph_decls_debug >= 2)
3698 fprintf (pph_logfile, " end normal dependences\n");
3703 /* Print the head of declaration T and its dependencies. N_BODY_TOKENS
3704 is the number of tokens taken by T's head. N_BODY_ITOKENS is the
3705 number of invisible tokens.
3707 BODY_TOKENS is the array of tokens in the head (note that the
3708 length of this array may be different than N_BODY_TOKENS, due to
3709 adjustments made by the caller).
3711 EXPOSURE indicates the exposure of T.
3713 N_SUBTOKENS is the number of tokens that declarations inside T's
3714 body have used up, those should be subtracted from the total number
3715 of tokens in T to avoid double counting. */
3717 static void
3718 pph_print_declaration_body (tree t, bool artificial,
3719 enum decl_exposure exposure,
3720 unsigned n_body_tokens, unsigned n_body_invis,
3721 VEC(cp_token, heap) *body_tokens)
3723 VEC(tree,gc) *sym_head_deps, *sym_body_deps;
3724 const char* msg;
3726 fprintf (pph_logfile, "declaration ");
3727 pph_debug_tree (t, true);
3729 fprintf (pph_logfile, " btok %u,%u", n_body_tokens, n_body_invis);
3731 /* FIXME pph: We want to get rid of most artificial tokens;
3732 this is temporary to find them. */
3733 if (artificial)
3734 msg = "artificial";
3735 else if (exposure == NEEDED)
3736 msg = "needed";
3737 else
3738 msg = "lazy";
3739 fprintf (pph_logfile, " %s", msg);
3741 fprintf (pph_logfile, "\n");
3743 pph_print_dependence (true, false, t, t); /* body depends on its head */
3745 if (flag_pph_decls_debug >= 2)
3746 fprintf (pph_logfile, " begin normal dependences\n");
3747 pph_locate_name_lookups_in (body_tokens, &sym_head_deps, &sym_body_deps);
3748 pph_print_dependences (true, false, t, sym_head_deps);
3749 pph_print_dependences (true, false, t, sym_body_deps);
3750 if (flag_pph_decls_debug >= 2)
3751 fprintf (pph_logfile, " end normal dependences\n");
3755 /* Compute the implicit cost of a method F. */
3757 static unsigned
3758 pph_find_special_methods (tree f)
3760 unsigned found = 0;
3761 tree o;
3762 if (TREE_CODE (f) == OVERLOAD)
3764 for (o = f; o; o = OVL_NEXT (o))
3765 found |= pph_find_special_methods (OVL_CURRENT (o));
3767 else if (TREE_CODE (f) == TEMPLATE_DECL)
3768 found |= pph_find_special_methods (DECL_TEMPLATE_RESULT (f));
3769 else
3771 gcc_assert (TREE_CODE (f) == FUNCTION_DECL);
3772 if (DECL_ARTIFICIAL (f))
3773 return found;
3774 if (DECL_CONSTRUCTOR_P (f))
3775 if (DECL_COPY_CONSTRUCTOR_P (f))
3776 found |= (1<<2); /* copy constructor */
3777 else
3778 found |= (1<<1); /* default constructor */
3779 else if (DECL_DESTRUCTOR_P (f))
3780 found |= (1<<0); /* destructor */
3781 else if (DECL_ASSIGNMENT_OPERATOR_P (f))
3782 found |= (1<<3); /* copy assign op */
3784 return found;
3787 /* Compute the implicit cost of a class type T_TYPE. */
3789 static unsigned
3790 pph_implicit_class_cost (tree t_type)
3792 VEC(tree,gc) *methods;
3793 unsigned idx;
3794 unsigned mbrs;
3795 unsigned cost = 0;
3796 unsigned found = 0;
3798 /* Gather general statistics. */
3799 unsigned fields = fields_length (t_type); /* also direct bases */
3800 unsigned vptr = (TYPE_POLYMORPHIC_P (t_type) ? 1 : 0);
3801 unsigned slots = fields + vptr;
3802 unsigned vbases = VEC_length (tree, CLASSTYPE_VBASECLASSES (t_type));
3803 unsigned vtables = list_length (CLASSTYPE_VTABLES (t_type));
3805 /* Assign cost of implicit special member variables. */
3806 /* These costs are somewhat arbitrary. */
3807 cost += 20 * (CLASSTYPE_TYPEINFO_VAR (t_type) != NULL); /* typeinfo */
3808 cost += 4 * vbases * vtables; /* virtual tables */
3810 /* Assign cost of implicit special member functions. */
3811 /* First find them. */
3812 methods = CLASSTYPE_METHOD_VEC (t_type);
3813 if (methods != NULL)
3814 for (idx = 0; idx < VEC_length (tree, methods); idx++)
3816 tree ovld = VEC_index (tree, methods, idx);
3817 if (ovld)
3818 found |= pph_find_special_methods (ovld);
3820 /* These costs are somewhat arbitrary. */
3821 /* FIXME pph: These queries seem to not work for templates.
3822 We can accept the inaccuracy for now. */
3823 mbrs = slots * 2 + vbases * 4;
3824 if (!(found & (1<<2))) /* copy constructor */
3826 if (TYPE_HAS_TRIVIAL_COPY_ASSIGN (t_type))
3827 cost += 4;
3828 else
3829 cost += (8 + 2*mbrs) * (vbases > 0 ? 2 : 1);
3831 if (!(found & (1<<1))) /* default constructor */
3832 if (!TYPE_HAS_TRIVIAL_DFLT (t_type))
3833 cost += 4 + mbrs;
3834 if (!(found & (1<<0))) /* destructor */
3835 if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (t_type))
3836 cost += (8 + 2*mbrs) * (vbases > 0 ? 2 : 1);
3837 if (!(found & (1<<3))) /* copy assign op */
3839 if (TYPE_HAS_TRIVIAL_COPY_ASSIGN (t_type))
3840 cost += 4;
3841 else
3842 cost += (8 + 2*mbrs);
3845 return cost;
3849 /* Print declaration T with the given EXPOSURE. If T has a body with
3850 N tokens, subtract N_SUBTOKENS from it before printing them.
3851 This is used when printing class declarations. The caller first
3852 prints all the declarations inside the class, followed by the
3853 class declaration itself, to avoid double counting tokens in the class
3854 body, they are subtracted from the total count.
3856 PRIMARY is true when T is the very first declaration captured
3857 during a pph_start_exposed/pph_stop_exposed region. If T is a
3858 member of a class, and it happens to be the first declaration
3859 captured, it means that T is an out-of-line definition.
3861 If T is a member of a class, and PARENT is the TYPE_DECL for that
3862 class, it means that we are printing the in-class declaration of T.
3863 In that case, when we print the parent, we should subtract the
3864 tokens attributed to T. So, in these cases return the total
3865 number of tokens printed in T's head and body. Otherwise,
3866 return 0. */
3868 static unsigned
3869 pph_print_declaration (tree t, enum decl_exposure exposure,
3870 unsigned n_subtokens, bool primary, tree parent)
3872 tree container = NULL;
3873 enum tree_code code = TREE_CODE (t);
3874 bool is_member = false;
3875 bool artificial = PPH_ARTIFICIAL (t);
3876 bool print_head = true, print_body = true;
3878 /* The cost of a declaration is proportional to the number of tokens.
3879 Artificial symbols are not represented in the file, so they do
3880 not have tokens. We represent their cost as a number of
3881 invisible tokens. */
3882 VEC(cp_token, heap) *head_tokens = pph_lookup_head_token_cache_for (t);
3883 unsigned n_head_tokens = VEC_length (cp_token, head_tokens);
3884 unsigned n_head_invis = 0;
3885 VEC(cp_token, heap) *body_tokens = pph_lookup_body_token_cache_for (t);
3886 unsigned n_body_tokens = VEC_length (cp_token, body_tokens);
3887 unsigned n_body_invis = 0;
3888 unsigned n_member_tokens = 0;
3890 /* If this is a member of a class, count the number of tokens in the
3891 member that overlap with the containing class. */
3892 if (code == FUNCTION_DECL || code == VAR_DECL)
3894 container = DECL_CONTEXT (t);
3895 if (container && CLASS_TYPE_P (container))
3897 is_member = true;
3898 if (parent && container == TREE_TYPE (parent))
3899 n_member_tokens = n_head_tokens + n_body_tokens;
3903 /* Now we need to adjust costs, and head/body printing. */
3905 if (code == VAR_DECL)
3907 if (artificial)
3908 /* Artificial static member variables get their token
3909 counts from the calling expression, which isn't helpful.
3910 Build the cost into the class instead. All of which
3911 means suppress this decl. */
3912 return 0;
3914 if (DECL_NONTRIVIALLY_INITIALIZED_P (t)
3915 && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t))
3916 n_body_invis += 10;
3918 if (is_member)
3920 if (primary) /* Must be an out-of-line declaration/definition. */
3922 /* Merge out-of-line member definitions into the body.
3923 This merge prevents two heads for the same symbol. */
3924 n_body_tokens += n_head_tokens;
3925 n_body_invis += n_head_invis;
3926 n_head_tokens = 0;
3927 n_head_invis = 0;
3928 print_head = false;
3929 /* Out-of-line member variable declarations are definitions,
3930 and hence need to be generated. */
3931 exposure = NEEDED;
3933 else /* Not primary; must be an in-line declaration/definition. */
3935 /* The only var bodies in the class are manifest constants;
3936 merge them into the head. */
3937 n_head_tokens += n_body_tokens;
3938 n_head_invis += n_body_invis;
3939 n_body_tokens = 0;
3940 n_body_invis = 0;
3941 print_body = false;
3944 else /* not is_member */
3946 if (exposure == EXPOSED)
3948 /* Merge manifest constants into the head.
3949 This code sweeps up extern declarations with no bodies,
3950 but that's okay. */
3951 n_head_tokens += n_body_tokens;
3952 n_head_invis += n_body_invis;
3953 n_body_tokens = 0;
3954 n_body_invis = 0;
3955 print_body = false;
3958 if (exposure == NEEDED)
3959 n_body_invis += 4; /* For emitting the actual variable declaration. */
3961 else if (code == FUNCTION_DECL)
3963 /* Pure function declarations get no body. */
3964 if (exposure == EXPOSED && !artificial
3965 && n_body_tokens == 0 && n_body_invis == 0)
3966 print_body = false;
3967 if (artificial)
3969 if (is_member)
3971 /* Artificial special member functions get their token
3972 counts from the calling expression, which isn't helpful.
3973 Build the cost into the class instead. All of which
3974 means suppress this decl. */
3975 return 0;
3979 else if (code == TYPE_DECL)
3981 tree t_type = TREE_TYPE (t);
3983 if (artificial)
3984 return 0;
3986 if (DECL_IMPLICIT_TYPEDEF_P (t)
3987 && CLASS_TYPE_P (t_type)
3988 && TYPE_LANG_SPECIFIC (t_type))
3990 tree tmpl_info;
3991 int generic;
3993 n_body_invis += pph_implicit_class_cost (t_type);
3995 tmpl_info = CLASSTYPE_TEMPLATE_INFO (t_type);
3996 if (tmpl_info)
3998 generic = CLASSTYPE_USE_TEMPLATE (t_type);
3999 if (generic == 1)
4001 /* Implicit instantiations have no visibile tokens. */
4002 n_head_invis += n_head_tokens;
4003 n_head_tokens = 0;
4004 n_body_invis += n_body_tokens;
4005 n_body_tokens = 0;
4007 else if (generic == 3)
4009 /* Explicit instantiations have no bodies,
4010 but they are work. This approximation is
4011 unjustified, but we are presuming that explicit
4012 instantiations are rare in application code. */
4013 n_body_invis += 15;
4014 exposure = NEEDED;
4016 if (generic != 2)
4018 bool defined;
4019 defined = CLASS_TYPE_P (t_type) && COMPLETE_TYPE_P (t_type);
4020 if (defined)
4021 pph_print_depend_template (tmpl_info, t);
4024 else if (primary)
4026 /* Now subtract the sum of members from the body of the class.
4027 This prevents double counting when emitting the parent.
4028 For non-primary class symbols, this value will be zero. */
4029 gcc_assert (n_body_tokens >= n_subtokens);
4030 n_body_tokens -= n_subtokens;
4033 else if (TREE_CODE (t_type) == ENUMERAL_TYPE)
4035 /* No additional work for enum. */
4037 else
4039 /* Not artificial, not a C++ class, not an enum;
4040 so must be a pure typedef. They have no body. */
4041 gcc_assert (n_body_tokens == 0 && n_body_invis == 0);
4042 print_body = false;
4046 if (print_head)
4047 pph_print_declaration_head (t, artificial, (is_member) ? container : NULL,
4048 n_head_tokens, n_head_invis, head_tokens);
4050 if (print_body)
4051 pph_print_declaration_body (t, artificial, exposure,
4052 n_body_tokens, n_body_invis, body_tokens);
4054 if (flag_pph_decls_debug >= 4)
4056 fprintf (pph_logfile, " Declarator head tokens: ");
4057 cp_lexer_debug_tokens ((VEC(cp_token, gc) *)head_tokens);
4058 fprintf (pph_logfile, " Declarator body tokens: ");
4059 cp_lexer_debug_tokens ((VEC(cp_token, gc) *)body_tokens);
4060 fprintf (pph_logfile, "\n");
4063 return n_member_tokens;
4066 static void
4067 pph_print_declarations (VEC(tree,heap) *v)
4069 unsigned i, j, n, first_ix;
4070 tree t, first, parent;
4071 enum decl_exposure exposure;
4072 unsigned n_subtokens = 0;
4074 if (VEC_empty (tree, v))
4075 return;
4077 /* If the first AST in V is a class/structure declaration, process
4078 the sub-declarations first. This will accumulate the tokens in
4079 the sub-declarations, so that when we print the class itself
4080 we don't double count the tokens in its body. */
4082 /* Skip over un-exposed declarations, like template parameters. */
4083 n = VEC_length (tree, v);
4084 for ( i = 0; VEC_iterate (tree, v, i, t); i++)
4086 exposure = pph_get_decl_exposure (t);
4087 if (exposure >= EXPOSED)
4088 break;
4090 if (i >= n)
4091 return; /* No exposed decls. */
4093 first = VEC_index (tree, v, i);
4094 if (VEC_length (tree, v) > i+1
4095 && TREE_CODE (first) == TYPE_DECL
4096 && CLASS_TYPE_P (TREE_TYPE (first)))
4098 parent = first;
4099 first_ix = i+1;
4101 else
4103 parent = NULL;
4104 first_ix = i;
4107 for (j = first_ix; VEC_iterate (tree, v, j, t); j++)
4109 exposure = pph_get_decl_exposure (t);
4110 if (exposure >= EXPOSED)
4111 n_subtokens += pph_print_declaration (t, exposure, 0U, i == j, parent);
4114 /* If we didn't print the first declaration, print it now. */
4115 if (first_ix > i)
4117 exposure = pph_get_decl_exposure (first);
4118 if (exposure >= EXPOSED)
4119 pph_print_declaration (first, exposure, n_subtokens, true, NULL);
4123 static void
4124 pph_print_trees_tokens (VEC(tree,heap) *v, cp_token *tok1, cp_token *tok2)
4126 VEC(cp_token, heap) *vtok;
4128 vtok = pph_print_copy_tokens (tok1, tok2);
4129 if (vtok == NULL)
4130 return;
4132 pph_print_token_range (v, vtok);
4133 pph_print_declarations (v);
4134 fprintf (pph_logfile, "\n");
4138 /* Intercept the result of a name lookup operation requested by the
4139 parser while we are intercepting AST creation. T is the result
4140 of a name lookup done by the parser. If this is the first time
4141 we see it, store it in pph_name_lookups. */
4143 void
4144 pph_catch_name_lookup (tree t)
4146 if (t == NULL_TREE || t == error_mark_node || pph_tree_catcher == NULL)
4147 return;
4149 timevar_push (TV_PPH_MANAGE);
4151 PPH_STATS_INCR (name_lookups, 1);
4153 if (the_parser->lexer)
4155 /* If we are parsing, we are stopped one token past the identifier
4156 that we have just looked up. Store the token where we have seen
4157 this identifier so that we can determine whether the identifier
4158 was accessed in a head or a body.
4160 Note that we do this for every instance we find for T, so that
4161 we can store all the locations where T was accessed from. */
4162 VEC(cp_token, heap) *tokens;
4163 cp_token *tok;
4164 void **slot;
4166 slot = pointer_map_insert (pph_nl_token_map, t);
4167 tokens = (VEC(cp_token, heap) *) *slot;
4168 tok = the_parser->lexer->next_token - 1;
4169 VEC_safe_push (cp_token, heap, tokens, tok);
4170 *slot = tokens;
4173 /* Make sure we do not store the same decl more than once. */
4174 if (pointer_set_insert (pph_name_lookups_set, t))
4176 timevar_pop (TV_PPH_MANAGE);
4177 return;
4180 VEC_safe_push (tree, heap, pph_name_lookups, t);
4181 timevar_pop (TV_PPH_MANAGE);
4185 /* Print statistics for the PPH cache. */
4187 static void
4188 pph_print_stats (void)
4190 fprintf (stderr, "\nPPH cache statistics\n");
4191 fprintf (stderr, "Number of tokens in the lexer: %lu\n",
4192 pph_stats.lexed_tokens);
4193 fprintf (stderr, "Number of tokens consumed by the parser: %lu\n",
4194 pph_stats.parsed_tokens);
4195 fprintf (stderr, "Number of declarations cached in: %lu\n",
4196 pph_stats.cached_decls);
4197 fprintf (stderr, "Number of declarations restored: %lu\n",
4198 pph_stats.restored_decls);
4199 fprintf (stderr, "Number of cached decl references: %lu\n",
4200 pph_stats.cached_refs);
4201 fprintf (stderr, "Number of name lookups: %lu\n",
4202 pph_stats.name_lookups);
4203 fprintf (stderr, "Number of bad lookups: %lu\n",
4204 pph_stats.bad_lookups);
4208 /* Initialize PPH support. */
4210 void
4211 pph_init (void)
4213 cpp_callbacks *cb;
4214 cpp_lookaside *table;
4216 if (flag_pph_logfile)
4218 pph_logfile = fopen (flag_pph_logfile, "w");
4219 if (!pph_logfile)
4220 fatal_error ("Cannot create %s for writing: %m", flag_pph_logfile);
4222 else
4223 pph_logfile = stdout;
4225 if (flag_pph_debug >= 1)
4226 fprintf (pph_logfile, "PPH: Initializing.\n");
4228 cb = cpp_get_callbacks (parse_in);
4229 cb->include = pph_include_handler;
4230 /* FIXME pph: Use file change instead.
4231 state->file_change_prev = cb->file_change;
4232 cb->file_change = pph_file_change;
4235 table = cpp_lt_exchange (parse_in,
4236 cpp_lt_create (cpp_lt_order, flag_pth_debug));
4237 gcc_assert (table == NULL);
4241 /* Finalize PPH support. */
4243 void
4244 pph_finish (void)
4246 if (pph_out_file != NULL)
4248 const char *offending_file = cpp_main_missing_guard (parse_in);
4249 if (offending_file == NULL)
4250 pph_write_file ();
4251 else
4252 error ("header lacks guard for PPH: %s", offending_file);
4255 if (flag_pph_stats)
4256 pph_print_stats ();
4258 if (flag_pph_debug >= 1)
4259 fprintf (pph_logfile, "PPH: Finishing.\n");
4261 if (flag_pph_logfile)
4262 fclose (pph_logfile);
4265 #include "gt-cp-pph.h"