diff options
-rw-r--r-- | llvm/test/tools/llvm-cov/Inputs/multiple-files2.covmapping | bin | 0 -> 136 bytes | |||
-rw-r--r-- | llvm/test/tools/llvm-cov/multiple-files.test | 20 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/CoverageReport.cpp | 58 |
3 files changed, 57 insertions, 21 deletions
diff --git a/llvm/test/tools/llvm-cov/Inputs/multiple-files2.covmapping b/llvm/test/tools/llvm-cov/Inputs/multiple-files2.covmapping Binary files differnew file mode 100644 index 00000000000..770817a5380 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/multiple-files2.covmapping diff --git a/llvm/test/tools/llvm-cov/multiple-files.test b/llvm/test/tools/llvm-cov/multiple-files.test index 0b3fb855fed..d0dbdd8c0fc 100644 --- a/llvm/test/tools/llvm-cov/multiple-files.test +++ b/llvm/test/tools/llvm-cov/multiple-files.test @@ -1,9 +1,15 @@ // RUN: llvm-profdata merge %S/Inputs/multiple-files.proftext -o %t.profdata -// RUN: llvm-cov report %S/Inputs/multiple-files.covmapping -instr-profile %t.profdata | FileCheck %s +// RUN: llvm-cov report %S/Inputs/multiple-files.covmapping -instr-profile %t.profdata | FileCheck %s -check-prefix=MANY_COMPONENTS +// RUN: llvm-cov report %S/Inputs/multiple-files2.covmapping -instr-profile %t.profdata | FileCheck %s -check-prefix=ONE_COMPONENT -// CHECK: Filename -// CHECK-NEXT: --- -// CHECK-NEXT: {{^}}a{{[/\\]}}f2.c -// CHECK-NEXT: {{^}}b{{[/\\]}}c{{[/\\]}}f4.c -// CHECK-NEXT: {{^}}b{{[/\\]}}f3.c -// CHECK-NEXT: {{^}}f1.c +// MANY_COMPONENTS: Filename +// MANY_COMPONENTS-NEXT: --- +// MANY_COMPONENTS-NEXT: {{^}}a{{[/\\]}}f2.c +// MANY_COMPONENTS-NEXT: {{^}}b{{[/\\]}}c{{[/\\]}}f4.c +// MANY_COMPONENTS-NEXT: {{^}}b{{[/\\]}}f3.c +// MANY_COMPONENTS-NEXT: {{^}}f1.c + +// ONE_COMPONENT: Filename +// ONE_COMPONENT-NEXT: --- +// ONE_COMPONENT-NEXT: {{^}}cov.c +// ONE_COMPONENT-NEXT: {{^}}cov.h diff --git a/llvm/tools/llvm-cov/CoverageReport.cpp b/llvm/tools/llvm-cov/CoverageReport.cpp index 78333d09ad8..6ae64ba8a3a 100644 --- a/llvm/tools/llvm-cov/CoverageReport.cpp +++ b/llvm/tools/llvm-cov/CoverageReport.cpp @@ -118,19 +118,51 @@ raw_ostream::Colors determineCoveragePercentageColor(const T &Info) { : raw_ostream::RED; } -/// \brief Determine the length of the longest common prefix of the strings in -/// \p Strings. -unsigned getLongestCommonPrefixLen(ArrayRef<std::string> Strings) { - unsigned LCP = Strings[0].size(); - for (unsigned I = 1, E = Strings.size(); LCP > 0 && I < E; ++I) { - unsigned Cursor; - StringRef S = Strings[I]; - for (Cursor = 0; Cursor < LCP && Cursor < S.size(); ++Cursor) - if (Strings[0][Cursor] != S[Cursor]) +/// \brief Get the number of redundant path components in each path in \p Paths. +unsigned getNumRedundantPathComponents(ArrayRef<std::string> Paths) { + // To start, set the number of redundant path components to the maximum + // possible value. + SmallVector<StringRef, 8> FirstPathComponents{sys::path::begin(Paths[0]), + sys::path::end(Paths[0])}; + unsigned NumRedundant = FirstPathComponents.size(); + + for (unsigned I = 1, E = Paths.size(); NumRedundant > 0 && I < E; ++I) { + StringRef Path = Paths[I]; + for (const auto &Component : + enumerate(make_range(sys::path::begin(Path), sys::path::end(Path)))) { + // Do not increase the number of redundant components: that would remove + // useful parts of already-visited paths. + if (Component.Index >= NumRedundant) break; - LCP = std::min(LCP, Cursor); + + // Lower the number of redundant components when there's a mismatch + // between the first path, and the path under consideration. + if (FirstPathComponents[Component.Index] != Component.Value) { + NumRedundant = Component.Index; + break; + } + } + } + + return NumRedundant; +} + +/// \brief Determine the length of the longest redundant prefix of the paths in +/// \p Paths. +unsigned getRedundantPrefixLen(ArrayRef<std::string> Paths) { + // If there's at most one path, no path components are redundant. + if (Paths.size() <= 1) + return 0; + + unsigned PrefixLen = 0; + unsigned NumRedundant = getNumRedundantPathComponents(Paths); + auto Component = sys::path::begin(Paths[0]); + for (unsigned I = 0; I < NumRedundant; ++I) { + auto LastComponent = Component; + ++Component; + PrefixLen += Component - LastComponent; } - return LCP; + return PrefixLen; } } // end anonymous namespace @@ -280,9 +312,7 @@ CoverageReport::prepareFileReports(const coverage::CoverageMapping &Coverage, FileCoverageSummary &Totals, ArrayRef<std::string> Files) { std::vector<FileCoverageSummary> FileReports; - unsigned LCP = 0; - if (Files.size() > 1) - LCP = getLongestCommonPrefixLen(Files); + unsigned LCP = getRedundantPrefixLen(Files); for (StringRef Filename : Files) { FileCoverageSummary Summary(Filename.drop_front(LCP)); |