aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcov.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2017-11-10 16:23:24 +0100
committerMartin Liska <marxin@gcc.gnu.org>2017-11-10 15:23:24 +0000
commite89ce41dbab07a9acafd900a3ab57eeb5d499276 (patch)
treebb60851e031de827e88d896c2c17c15f615561a9 /gcc/gcov.c
parent127ef36981ebdfbe3be0f8df710090642a2a4abe (diff)
downloadgcc-e89ce41dbab07a9acafd900a3ab57eeb5d499276.zip
gcc-e89ce41dbab07a9acafd900a3ab57eeb5d499276.tar.gz
gcc-e89ce41dbab07a9acafd900a3ab57eeb5d499276.tar.bz2
GCOV: create one intermediate file per a gcno file (PR gcov-profile/82702).
2017-11-10 Martin Liska <mliska@suse.cz> PR gcov-profile/82702 * gcov.c (main): Handle intermediate files in a different way. (get_gcov_intermediate_filename): New function. (output_gcov_file): Remove support of intermediate files. (generate_results): Allocate intermediate file. (release_structures): Clean-up properly fn_end. (output_intermediate_file): Start iterating with line 1. From-SVN: r254629
Diffstat (limited to 'gcc/gcov.c')
-rw-r--r--gcc/gcov.c96
1 files changed, 76 insertions, 20 deletions
diff --git a/gcc/gcov.c b/gcc/gcov.c
index 7152372..3c2c270 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -784,11 +784,13 @@ main (int argc, char **argv)
printf ("Processing file %d out of %d\n", argno - first_arg + 1,
argc - first_arg);
process_file (argv[argno]);
- }
-
- generate_results (multiple_files ? NULL : argv[argc - 1]);
- release_structures ();
+ if (flag_intermediate_format || argno == argc - 1)
+ {
+ generate_results (argv[argno]);
+ release_structures ();
+ }
+ }
return 0;
}
@@ -991,6 +993,31 @@ output_intermediate_line (FILE *f, line_info *line, unsigned line_num)
}
}
+/* Get the name of the gcov file. The return value must be free'd.
+
+ It appends the '.gcov' extension to the *basename* of the file.
+ The resulting file name will be in PWD.
+
+ e.g.,
+ input: foo.da, output: foo.da.gcov
+ input: a/b/foo.cc, output: foo.cc.gcov */
+
+static char *
+get_gcov_intermediate_filename (const char *file_name)
+{
+ const char *gcov = ".gcov";
+ char *result;
+ const char *cptr;
+
+ /* Find the 'basename'. */
+ cptr = lbasename (file_name);
+
+ result = XNEWVEC (char, strlen (cptr) + strlen (gcov) + 1);
+ sprintf (result, "%s%s", cptr, gcov);
+
+ return result;
+}
+
/* Output the result in intermediate format used by 'lcov'.
The intermediate format contains a single file named 'foo.cc.gcov',
@@ -1017,7 +1044,7 @@ output_intermediate_file (FILE *gcov_file, source_info *src)
flag_demangled_names ? (*it)->demangled_name : (*it)->name);
}
- for (unsigned line_num = 0; line_num <= src->lines.size (); line_num++)
+ for (unsigned line_num = 1; line_num <= src->lines.size (); line_num++)
{
vector<function_t *> fns = src->get_functions_at_location (line_num);
@@ -1200,19 +1227,16 @@ output_gcov_file (const char *file_name, source_info *src)
{
FILE *gcov_file = fopen (gcov_file_name, "w");
if (gcov_file)
- {
- fnotice (stdout, "Creating '%s'\n", gcov_file_name);
-
- if (flag_intermediate_format)
- output_intermediate_file (gcov_file, src);
- else
- output_lines (gcov_file, src);
- if (ferror (gcov_file))
- fnotice (stderr, "Error writing output file '%s'\n", gcov_file_name);
- fclose (gcov_file);
- }
+ {
+ fnotice (stdout, "Creating '%s'\n", gcov_file_name);
+ output_lines (gcov_file, src);
+ if (ferror (gcov_file))
+ fnotice (stderr, "Error writing output file '%s'\n",
+ gcov_file_name);
+ fclose (gcov_file);
+ }
else
- fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
+ fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
}
else
{
@@ -1226,6 +1250,8 @@ static void
generate_results (const char *file_name)
{
function_t *fn;
+ FILE *gcov_intermediate_file = NULL;
+ char *gcov_intermediate_filename = NULL;
for (fn = functions; fn; fn = fn->next)
{
@@ -1256,6 +1282,19 @@ generate_results (const char *file_name)
file_name = canonicalize_name (file_name);
}
+ if (flag_gcov_file && flag_intermediate_format)
+ {
+ /* Open the intermediate file. */
+ gcov_intermediate_filename = get_gcov_intermediate_filename (file_name);
+ gcov_intermediate_file = fopen (gcov_intermediate_filename, "w");
+ if (!gcov_intermediate_file)
+ {
+ fnotice (stderr, "Cannot open intermediate output file %s\n",
+ gcov_intermediate_filename);
+ return;
+ }
+ }
+
for (vector<source_info>::iterator it = sources.begin ();
it != sources.end (); it++)
{
@@ -1280,9 +1319,21 @@ generate_results (const char *file_name)
total_executed += src->coverage.lines_executed;
if (flag_gcov_file)
{
- output_gcov_file (file_name, src);
- fnotice (stdout, "\n");
- }
+ if (flag_intermediate_format)
+ /* Output the intermediate format without requiring source
+ files. This outputs a section to a *single* file. */
+ output_intermediate_file (gcov_intermediate_file, src);
+ else
+ output_gcov_file (file_name, src);
+ fnotice (stdout, "\n");
+ }
+ }
+
+ if (flag_gcov_file && flag_intermediate_format)
+ {
+ /* Now we've finished writing the intermediate file. */
+ fclose (gcov_intermediate_file);
+ XDELETEVEC (gcov_intermediate_filename);
}
if (!file_name)
@@ -1296,11 +1347,16 @@ release_structures (void)
{
function_t *fn;
+ sources.resize (0);
+ names.resize (0);
+
while ((fn = functions))
{
functions = fn->next;
delete fn;
}
+
+ fn_end = &functions;
}
/* Generate the names of the graph and data files. If OBJECT_DIRECTORY