diff --git a/llvm/docs/CommandGuide/llvm-cov.rst b/llvm/docs/CommandGuide/llvm-cov.rst index 71924e997d934a6f0725852a7cb3328f903da6ff..6e90760cbaf683fcc14fcebd7079e53f8e206335 100644 --- a/llvm/docs/CommandGuide/llvm-cov.rst +++ b/llvm/docs/CommandGuide/llvm-cov.rst @@ -150,6 +150,11 @@ OPTIONS Display the version of llvm-cov. +.. option:: -x, --hash-filenames + + Use md5 hash of file name when naming the coverage output files. The source + file name will be suffixed by ``##`` followed by MD5 hash calculated for it. + EXIT STATUS ^^^^^^^^^^^ diff --git a/llvm/include/llvm/ProfileData/GCOV.h b/llvm/include/llvm/ProfileData/GCOV.h index 27b76b577c10d459e48bce6415486ac1198995c0..9e2d27f083faa5232a779535c0dc4f15ea204bee 100644 --- a/llvm/include/llvm/ProfileData/GCOV.h +++ b/llvm/include/llvm/ProfileData/GCOV.h @@ -44,9 +44,10 @@ enum GCOVVersion { V402, V404, V704 }; /// A struct for passing gcov options between functions. struct Options { - Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N) + Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N, bool X) : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F), - PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N) {} + PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N), + HashFilenames(X) {} bool AllBlocks; bool BranchInfo; @@ -56,6 +57,7 @@ struct Options { bool UncondBranch; bool LongFileNames; bool NoOutput; + bool HashFilenames; }; } // end namespace GCOV diff --git a/llvm/lib/ProfileData/GCOV.cpp b/llvm/lib/ProfileData/GCOV.cpp index 41ea7555b9f096c4cc7d14bc1f4ebdb55790c560..af4527024b485bc8458e5177bc3074cdcb1fbba1 100644 --- a/llvm/lib/ProfileData/GCOV.cpp +++ b/llvm/lib/ProfileData/GCOV.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" #include "llvm/Support/Path.h" +#include "llvm/Support/MD5.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -686,7 +687,15 @@ std::string FileInfo::getCoveragePath(StringRef Filename, if (Options.LongFileNames && !Filename.equals(MainFilename)) CoveragePath = mangleCoveragePath(MainFilename, Options.PreservePaths) + "##"; - CoveragePath += mangleCoveragePath(Filename, Options.PreservePaths) + ".gcov"; + CoveragePath += mangleCoveragePath(Filename, Options.PreservePaths); + if (Options.HashFilenames) { + MD5 Hasher; + MD5::MD5Result Result; + Hasher.update(Filename.str()); + Hasher.final(Result); + CoveragePath += "##" + Result.digest().str().str(); + } + CoveragePath += ".gcov"; return CoveragePath; } diff --git a/llvm/test/tools/llvm-cov/Inputs/test_hash.output b/llvm/test/tools/llvm-cov/Inputs/test_hash.output new file mode 100644 index 0000000000000000000000000000000000000000..3f8b3f614d5a1dd79082a5028183d5bf39e28117 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/test_hash.output @@ -0,0 +1,8 @@ +File 'srcdir/./nested_dir/../test.cpp' +Lines executed:84.21% of 38 +srcdir/./nested_dir/../test.cpp:creating 'test.cpp##a806e5b3093cd6f683da88c0da150daf.gcov' + +File 'srcdir/./nested_dir/../test.h' +Lines executed:100.00% of 1 +srcdir/./nested_dir/../test.h:creating 'test.h##0cbee7e2421fa4517420ac4f935620ca.gcov' + diff --git a/llvm/test/tools/llvm-cov/llvm-cov.test b/llvm/test/tools/llvm-cov/llvm-cov.test index d460f37da2a49a66652c06fc5d9ef05c94839119..1ddbdad15cd281418934fa882885fa81ec80a7d1 100644 --- a/llvm/test/tools/llvm-cov/llvm-cov.test +++ b/llvm/test/tools/llvm-cov/llvm-cov.test @@ -63,6 +63,11 @@ RUN: llvm-cov gcov -lp -gcno test_paths.gcno -gcda test_paths.gcda srcdir/../tes RUN: diff -aub test_paths.cpp.gcov srcdir#^#test_paths.cpp##srcdir#nested_dir#^#test.cpp.gcov RUN: diff -aub test_paths.h.gcov srcdir#^#test_paths.cpp##srcdir#nested_dir#^#test.h.gcov +# Hash pathnames. +RUN: llvm-cov gcov -x -gcno test_paths.gcno -gcda test_paths.gcda srcdir/../test_paths.cpp | diff -u test_hash.output - +RUN: diff -aub test_paths.cpp.gcov test.cpp##a806e5b3093cd6f683da88c0da150daf.gcov +RUN: diff -aub test_paths.h.gcov test.h##0cbee7e2421fa4517420ac4f935620ca.gcov + # Function summaries. This changes stdout, but not the gcov files. RUN: llvm-cov gcov test.c -f | diff -u test_-f.output - RUN: diff -aub test_no_options.cpp.gcov test.cpp.gcov diff --git a/llvm/tools/llvm-cov/gcov.cpp b/llvm/tools/llvm-cov/gcov.cpp index 58ef2cf0219a12042c9a949bc06cfd874d23d2e2..8a00ff64711fbd2de266eb2135968ef57b05f229 100644 --- a/llvm/tools/llvm-cov/gcov.cpp +++ b/llvm/tools/llvm-cov/gcov.cpp @@ -124,6 +124,11 @@ int gcovMain(int argc, const char *argv[]) { "(requires -b)")); cl::alias UncondBranchA("unconditional-branches", cl::aliasopt(UncondBranch)); + cl::opt HashFilenames("x", cl::Grouping, cl::init(false), + cl::desc("Hash long pathnames")); + cl::alias HashFilenamesA("hash-filenames", cl::aliasopt(HashFilenames)); + + cl::OptionCategory DebugCat("Internal and debugging options"); cl::opt DumpGCOV("dump", cl::init(false), cl::cat(DebugCat), cl::desc("Dump the gcov file to stderr")); @@ -135,7 +140,8 @@ int gcovMain(int argc, const char *argv[]) { cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); GCOV::Options Options(AllBlocks, BranchProb, BranchCount, FuncSummary, - PreservePaths, UncondBranch, LongNames, NoOutput); + PreservePaths, UncondBranch, LongNames, NoOutput, + HashFilenames); for (const auto &SourceFile : SourceFiles) reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV,