Index: llvm/trunk/docs/CommandGuide/llvm-cov.rst =================================================================== --- llvm/trunk/docs/CommandGuide/llvm-cov.rst +++ llvm/trunk/docs/CommandGuide/llvm-cov.rst @@ -150,6 +150,11 @@ 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 ^^^^^^^^^^^ Index: llvm/trunk/include/llvm/ProfileData/GCOV.h =================================================================== --- llvm/trunk/include/llvm/ProfileData/GCOV.h +++ llvm/trunk/include/llvm/ProfileData/GCOV.h @@ -44,9 +44,10 @@ /// 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 @@ bool UncondBranch; bool LongFileNames; bool NoOutput; + bool HashFilenames; }; } // end namespace GCOV Index: llvm/trunk/lib/ProfileData/GCOV.cpp =================================================================== --- llvm/trunk/lib/ProfileData/GCOV.cpp +++ llvm/trunk/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 @@ 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; } Index: llvm/trunk/test/tools/llvm-cov/Inputs/test_hash.output =================================================================== --- llvm/trunk/test/tools/llvm-cov/Inputs/test_hash.output +++ llvm/trunk/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' + Index: llvm/trunk/test/tools/llvm-cov/llvm-cov.test =================================================================== --- llvm/trunk/test/tools/llvm-cov/llvm-cov.test +++ llvm/trunk/test/tools/llvm-cov/llvm-cov.test @@ -63,6 +63,11 @@ 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 Index: llvm/trunk/tools/llvm-cov/gcov.cpp =================================================================== --- llvm/trunk/tools/llvm-cov/gcov.cpp +++ llvm/trunk/tools/llvm-cov/gcov.cpp @@ -124,6 +124,11 @@ "(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 @@ 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,