This patch is an enhanced variant of -H. It prints more information about the included ...
13 years, 4 months ago
(2011-11-14 17:01:27 UTC)
#1
This patch is an enhanced variant of -H. It prints more information about
the included files. I'm using it as input to a tool to automatically
generate PPH mappings for large TUs.
I don't think this will survive for long, but it is useful for now.
Tested on x86_64. Committed to branch.
Diego.
* c.opt (fpph-include-tree): New.
(fpph-logfile, fpph-map): Tidy.
cp/ChangeLog.pph
* parser.c (c_parse_file): Call pph_init_include_tree.
* pph.c (pph_init_include_tree): New.
(flatten_name): New.
(pph_file_change_handler): New.
(pph_include_handler_for_map): New.
(pph_init_map_file): New.
(pph_finish_map_file): New.
* pph.h (pph_init_include_tree): New.
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index d10fd7a..62ad01c 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -961,13 +961,17 @@ C++ Joined MissingArgError(missing filename after %qs)
-fpph-hdr=<base-name> A mapping from <base-name>.h to <base-name>.pph
fpph-logfile=
-C++ Joined RejectNegative Var(flag_pph_logfile)
+C++ Joined RejectNegative MissingArgError(missing filename after %qs)
Var(flag_pph_logfile)
-fpph-logfile=<file-name> Emit PPH debug information to <file-name>
fpph-map=
-C++ Joined MissingArgError(missing filename after %qs)
+C++ Joined RejectNegative MissingArgError(missing filename after %qs)
Var(flag_pph_map)
-fpph-map=<file-name> A file of mappings from #include to PPH file
+fpph-include-tree
+C++ Var(flag_pph_include_tree)
+-fpph-include-tree Print the include tree for the current TU to stderr
+
fpph-tracer=
C++ Joined RejectNegative UInteger Var(flag_pph_tracer)
-fpph-tracer Enable tracing of PPH streaming operations
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 8947be1..5ee3c74 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -26321,6 +26321,9 @@ c_parse_file (void)
if (pph_enabled_p ())
pph_init ();
+ if (flag_pph_include_tree)
+ pph_init_include_tree ();
+
the_parser = cp_parser_new ();
push_deferring_access_checks (flag_access_control
? dk_no_deferred : dk_no_check);
diff --git a/gcc/cp/pph.c b/gcc/cp/pph.c
index 206a7c6..7dc2be3 100644
--- a/gcc/cp/pph.c
+++ b/gcc/cp/pph.c
@@ -158,7 +158,12 @@ pph_is_valid_here (const char *name, location_t loc)
}
-/* Record a #include or #include_next for PPH. */
+/* Record a #include or #include_next for PPH.
+ READER is the main pre-processor object, LOC is the location where
+ the #include is being emitted from, DNAME is the name of the
+ #include directive used, NAME is the canonical name of the file being
+ included, ANGLE_BRACKETS is non-zero if this #include uses <> and
+ TOK_P is a pointer to the current token being pre-processed. */
static bool
pph_include_handler (cpp_reader *reader,
@@ -265,3 +270,133 @@ pph_finish (void)
if (flag_pph_logfile)
fclose (pph_logfile);
}
+
+
+/* PPH include tree dumper. Each entry in this file has the format:
+
+ DEPTH|SYSP|DNAME|CANONICAL-NAME|FULL-NAME|PPH-NAME
+
+ Where:
+ DEPTH is the include depth of the file.
+ SYSP 1 for a system header
+ 2 for a C system header that needs 'extern "C"'
+ 0 otherwise.
+ DNAME name of the #include directive used.
+ CANONICAL-NAME is the name of the file as specified by the
+ #include directive.
+ FULL-NAME is the full path name where the included file
+ was found by the pre-processor.
+ PPH-NAME is the name of the associated PPH file. */
+typedef struct {
+ /* Name of current #include directive. */
+ const unsigned char *dname;
+
+ /* Canonical name of file being included. */
+ const char *name;
+
+ /* Previous libcpp #include handler. */
+ void (*prev_file_change) (cpp_reader *, const struct line_map *);
+
+ /* Previous libcpp file change handler. */
+ bool (*prev_include) (cpp_reader *, source_location, const unsigned char *,
+ const char *, int, const cpp_token **);
+} pph_include_tree_dumper;
+
+static pph_include_tree_dumper tree_dumper;
+
+
+/* Return a copy of NAME with the characters '/' and '.' replaced with
+ '_'. The caller is reponsible for freeing the returned string. */
+
+static char *
+flatten_name (const char *name)
+{
+ char *str = xstrdup (name);
+ size_t i;
+
+ for (i = 0; i < strlen (str); i++)
+ if (str[i] == DIR_SEPARATOR || str[i] == '.')
+ str[i] = '_';
+
+ return str;
+}
+
+
+/* File change handler for libcpp. READER is the main pre-processor object,
+ MAP is the line map entry for the file that we are entering into. */
+
+static void
+pph_file_change_handler (cpp_reader *reader, const struct line_map *map)
+{
+ char *flat;
+
+ if (tree_dumper.prev_file_change)
+ tree_dumper.prev_file_change (reader, map);
+
+ /* We are only interested in line maps that describe a new file being
+ entered. */
+ if (map == NULL || map->reason != LC_ENTER)
+ return;
+
+ /* Emit a line to the map file with the format:
+
+ DEPTH|SYSP|DNAME|CANONICAL-NAME|FULL-NAME|PPH-NAME
+ */
+ flat = flatten_name (map->to_file);
+ fprintf (stderr, "%d|%d|%s|%s|%s|%s.pph\n", line_table->depth, map->sysp,
+ tree_dumper.dname, tree_dumper.name, map->to_file, flat);
+ free (flat);
+ tree_dumper.dname = NULL;
+ tree_dumper.name = NULL;
+}
+
+
+/* #include handler for libcpp. READER is the main pre-processor object,
+ LOC is the location where the #include is being emitted from, DNAME
+ is the name of the #include directive used, NAME is the canonical
+ name of the file being included, ANGLE_BRACKETS is non-zero if this
+ #include uses <> and TOK_P is a pointer to the current token being
+ pre-processed. */
+
+static bool
+pph_include_handler_for_map (cpp_reader *reader,
+ location_t loc,
+ const unsigned char *dname,
+ const char *name,
+ int angle_brackets,
+ const cpp_token **tok_p)
+{
+ bool retval = true;
+
+ if (tree_dumper.prev_include)
+ retval &= tree_dumper.prev_include (reader, loc, dname, name,
+ angle_brackets, tok_p);
+ tree_dumper.dname = dname;
+ tree_dumper.name = name;
+
+ return retval;
+}
+
+
+/* Initialize the #include tree dumper. */
+
+void
+pph_init_include_tree (void)
+{
+ cpp_callbacks *cb;
+
+ memset (&tree_dumper, 0, sizeof (tree_dumper));
+
+ if (pph_enabled_p ())
+ fatal_error ("do not use -fpph-map-gen with any other PPH flag");
+
+ /* Set up the libcpp handler for file change events. Each event
+ will generate a new entry in the map file. */
+ cb = cpp_get_callbacks (parse_in);
+
+ tree_dumper.prev_file_change = cb->file_change;
+ cb->file_change = pph_file_change_handler;
+
+ tree_dumper.prev_include = cb->include;
+ cb->include = pph_include_handler_for_map;
+}
diff --git a/gcc/cp/pph.h b/gcc/cp/pph.h
index 2a346fd..571927d 100644
--- a/gcc/cp/pph.h
+++ b/gcc/cp/pph.h
@@ -142,6 +142,7 @@ extern void pph_init (void);
extern void pph_finish (void);
extern void pph_dump_location (FILE *file, location_t loc);
extern void pph_dump_tree_name (FILE *file, tree t, int flags);
+extern void pph_init_include_tree (void);
/* In pph-streamer-out.c. */
extern void pph_out_uint (pph_stream *stream, unsigned int value);
--
1.7.3.1
--
This patch is available for review at http://codereview.appspot.com/5376093
Issue 5376093: [pph] Add flag -fpph-include-tree
(Closed)
Created 13 years, 4 months ago by Diego Novillo
Modified 13 years ago
Reviewers:
Base URL:
Comments: 0