[llvm] r281011 - [llvm-cov] Emit a summary in the report directory's index

Vedant Kumar via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 8 18:32:55 PDT 2016


Author: vedantk
Date: Thu Sep  8 20:32:55 2016
New Revision: 281011

URL: http://llvm.org/viewvc/llvm-project?rev=281011&view=rev
Log:
[llvm-cov] Emit a summary in the report directory's index

llvm-cov writes out an index file in '-output-dir' mode, albeit not a
very informative one. Try to fix that by using the CoverageReport API to
include some basic summary information in the index file.

Modified:
    llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp
    llvm/trunk/test/tools/llvm-cov/style.test
    llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
    llvm/trunk/tools/llvm-cov/SourceCoverageView.h
    llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.cpp
    llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.h
    llvm/trunk/tools/llvm-cov/SourceCoverageViewText.cpp
    llvm/trunk/tools/llvm-cov/SourceCoverageViewText.h

Modified: llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp?rev=281011&r1=281010&r2=281011&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp (original)
+++ llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp Thu Sep  8 20:32:55 2016
@@ -35,9 +35,9 @@ int main() {
 // RUN: FileCheck -check-prefixes=TEXT,WHOLE-FILE -input-file %t.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %s
 // RUN: FileCheck -check-prefixes=TEXT,FILTER -input-file %t.dir/functions.txt %s
 //
-// Test index creation.
-// RUN: FileCheck -check-prefix=INDEX -input-file %t.dir/index.txt %s
-// INDEX: showLineExecutionCounts.cpp.txt
+// RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -name=main 2>/dev/null > %t.export.json
+// RUN: FileCheck -input-file %t.export.json %S/Inputs/lineExecutionCounts.json
+// RUN: cat %t.export.json | %python -c "import json, sys; json.loads(sys.stdin.read())"
 //
 // Test html output.
 // RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.html.dir -instr-profile %t.profdata -filename-equivalence %s
@@ -69,7 +69,24 @@ int main() {
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>}
 // HTML-WHOLE-FILE: <td class='line-number'><a name='L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='uncovered-line'></td><td class='code'><pre>// after
 // HTML-FILTER-NOT: <td class='line-number'><a name='L[[@LINE-45]]'><pre>[[@LINE-45]]</pre></a></td><td class='uncovered-line'></td><td class='code'><pre>// after
-
-// RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -name=main 2>/dev/null > %t.export.json
-// RUN: FileCheck -input-file %t.export.json %S/Inputs/lineExecutionCounts.json
-// RUN: cat %t.export.json | %python -c "import json, sys; json.loads(sys.stdin.read())"
+//
+// Test index creation.
+// RUN: FileCheck -check-prefix=TEXT-INDEX -input-file %t.dir/index.txt %s
+// TEXT-INDEX: Filename
+// TEXT-INDEX-NEXT: ---
+// TEXT-INDEX-NEXT: {{.*}}showLineExecutionCounts.cpp
+//
+// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.html.dir/index.html %s
+// HTML-INDEX-LABEL: <table>
+// HTML-INDEX: <td class='column-entry'>Filename</td>
+// HTML-INDEX: <td class='column-entry'>Region Coverage</td>
+// HTML-INDEX: <td class='column-entry'>Function Coverage</td>
+// HTML-INDEX: <td class='column-entry'>Line Coverage</td>
+// HTML-INDEX: <a href='coverage{{.*}}showLineExecutionCounts.cpp.html'{{.*}}showLineExecutionCounts.cpp</a>
+// HTML-INDEX: <td class='column-entry-red'>
+// HTML-INDEX: 70.00% (7/10)
+// HTML-INDEX: <td class='column-entry-green'>
+// HTML-INDEX: 100.00% (1/1)
+// HTML-INDEX: <td class='column-entry-yellow'>
+// HTML-INDEX: 80.00% (16/20)
+// HTML-INDEX: TOTALS

Modified: llvm/trunk/test/tools/llvm-cov/style.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/style.test?rev=281011&r1=281010&r2=281011&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/style.test (original)
+++ llvm/trunk/test/tools/llvm-cov/style.test Thu Sep  8 20:32:55 2016
@@ -15,6 +15,11 @@ STYLE-DAG: .source-name-title
 STYLE-DAG: .centered
 STYLE-DAG: .expansion-view
 STYLE-DAG: .line-number
+STYLE-DAG: .light-row
+STYLE-DAG: .column-entry
+STYLE-DAG: .column-entry-yellow
+STYLE-DAG: .column-entry-red
+STYLE-DAG: .column-entry-green
 STYLE-DAG: .covered-line
 STYLE-DAG: .uncovered-line
 STYLE-DAG: .tooltip

Modified: llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CodeCoverage.cpp?rev=281011&r1=281010&r2=281011&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CodeCoverage.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CodeCoverage.cpp Thu Sep  8 20:32:55 2016
@@ -679,7 +679,7 @@ int CodeCoverageTool::show(int argc, con
 
   // Create an index out of the source files.
   if (ViewOpts.hasOutputDirectory()) {
-    if (Error E = Printer->createIndexFile(SourceFiles)) {
+    if (Error E = Printer->createIndexFile(SourceFiles, *Coverage)) {
       error("Could not create index file!", toString(std::move(E)));
       return 1;
     }

Modified: llvm/trunk/tools/llvm-cov/SourceCoverageView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/SourceCoverageView.h?rev=281011&r1=281010&r2=281011&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/SourceCoverageView.h (original)
+++ llvm/trunk/tools/llvm-cov/SourceCoverageView.h Thu Sep  8 20:32:55 2016
@@ -142,7 +142,8 @@ public:
   virtual void closeViewFile(OwnedStream OS) = 0;
 
   /// \brief Create an index which lists reports for the given source files.
-  virtual Error createIndexFile(ArrayRef<StringRef> SourceFiles) = 0;
+  virtual Error createIndexFile(ArrayRef<StringRef> SourceFiles,
+                                const coverage::CoverageMapping &Coverage) = 0;
 
   /// @}
 };

Modified: llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.cpp?rev=281011&r1=281010&r2=281011&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.cpp (original)
+++ llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.cpp Thu Sep  8 20:32:55 2016
@@ -11,11 +11,13 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "CoverageReport.h"
 #include "SourceCoverageViewHTML.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
 #include "llvm/Support/Path.h"
 
 using namespace llvm;
@@ -73,7 +75,7 @@ const char *BeginHeader =
 
 const char *CSSForCoverage =
     R"(.red {
-  background-color: #FFD0D0;
+  background-color: #ffd0d0;
 }
 .cyan {
   background-color: cyan;
@@ -110,6 +112,25 @@ pre {
 table {
   border-collapse: collapse;
 }
+.light-row {
+  background: #ffffff;
+  border: 1px solid #dbdbdb;
+}
+.column-entry {
+  text-align: right;
+}
+.column-entry-yellow {
+  text-align: right;
+  background-color: #ffffd0;
+}
+.column-entry-red {
+  text-align: right;
+  background-color: #ffd0d0;
+}
+.column-entry-green {
+  text-align: right;
+  background-color: #d0ffd0;
+}
 .line-number {
   text-align: right;
   color: #aaa;
@@ -284,16 +305,88 @@ void CoveragePrinterHTML::closeViewFile(
   emitEpilog(*OS.get());
 }
 
-Error CoveragePrinterHTML::createIndexFile(ArrayRef<StringRef> SourceFiles) {
+/// Emit column labels for the table in the index.
+static void emitColumnLabelsForIndex(raw_ostream &OS) {
+  SmallVector<std::string, 4> Columns;
+  for (const char *Label :
+       {"Filename", "Region Coverage", "Function Coverage", "Line Coverage"})
+    Columns.emplace_back(tag("td", Label, "column-entry"));
+  OS << tag("tr", join(Columns.begin(), Columns.end(), ""));
+}
+
+/// Render a file coverage summary (\p FCS) in a table row. If \p IsTotals is
+/// false, link the summary to \p SF.
+void CoveragePrinterHTML::emitFileSummary(raw_ostream &OS, StringRef SF,
+                                          const FileCoverageSummary &FCS,
+                                          bool IsTotals) const {
+  SmallVector<std::string, 4> Columns;
+
+  // Format a coverage triple and add the result to the list of columns.
+  auto AddCoverageTripleToColumn = [&Columns](unsigned Hit, unsigned Total,
+                                              float Pctg) {
+    std::string S;
+    {
+      raw_string_ostream RSO{S};
+      RSO << format("%*.2f", 7, Pctg) << "% (" << Hit << '/' << Total << ')';
+    }
+    const char *CellClass = "column-entry-yellow";
+    if (Pctg < 80.0)
+      CellClass = "column-entry-red";
+    else if (Hit == Total)
+      CellClass = "column-entry-green";
+    Columns.emplace_back(tag("td", tag("pre", S, "code"), CellClass));
+  };
+
+  // Simplify the display file path, and wrap it in a link if requested.
+  std::string Filename;
+  SmallString<128> LinkTextStr(sys::path::relative_path(FCS.Name));
+  sys::path::remove_dots(LinkTextStr, /*remove_dot_dots=*/true);
+  sys::path::native(LinkTextStr);
+  std::string LinkText = escape(LinkTextStr, Opts);
+  if (IsTotals) {
+    Filename = LinkText;
+  } else {
+    std::string LinkTarget =
+        escape(getOutputPath(SF, "html", /*InToplevel=*/false), Opts);
+    Filename = a(LinkTarget, LinkText);
+  }
+
+  Columns.emplace_back(tag("td", tag("pre", Filename, "code")));
+  AddCoverageTripleToColumn(
+      FCS.RegionCoverage.NumRegions - FCS.RegionCoverage.NotCovered,
+      FCS.RegionCoverage.NumRegions, FCS.RegionCoverage.getPercentCovered());
+  AddCoverageTripleToColumn(FCS.FunctionCoverage.Executed,
+                            FCS.FunctionCoverage.NumFunctions,
+                            FCS.FunctionCoverage.getPercentCovered());
+  AddCoverageTripleToColumn(
+      FCS.LineCoverage.NumLines - FCS.LineCoverage.NotCovered,
+      FCS.LineCoverage.NumLines, FCS.LineCoverage.getPercentCovered());
+
+  OS << tag("tr", join(Columns.begin(), Columns.end(), ""), "light-row");
+}
+
+Error CoveragePrinterHTML::createIndexFile(
+    ArrayRef<StringRef> SourceFiles,
+    const coverage::CoverageMapping &Coverage) {
+  // Emit the default stylesheet.
+  auto CSSOrErr = createOutputStream("style", "css", /*InToplevel=*/true);
+  if (Error E = CSSOrErr.takeError())
+    return E;
+
+  OwnedStream CSS = std::move(CSSOrErr.get());
+  CSS->operator<<(CSSForCoverage);
+
+  // Emit a file index along with some coverage statistics.
   auto OSOrErr = createOutputStream("index", "html", /*InToplevel=*/true);
   if (Error E = OSOrErr.takeError())
     return E;
   auto OS = std::move(OSOrErr.get());
   raw_ostream &OSRef = *OS.get();
 
-  // Emit a table containing links to reports for each file in the covmapping.
   assert(Opts.hasOutputDirectory() && "No output directory for index file");
   emitPrelude(OSRef, Opts, getPathToStyle(""));
+
+  // Emit some basic information about the coverage report.
   if (Opts.hasProjectTitle())
     OSRef << BeginProjectTitleDiv
           << tag("span", escape(Opts.ProjectTitle, Opts)) << EndProjectTitleDiv;
@@ -305,28 +398,19 @@ Error CoveragePrinterHTML::createIndexFi
           << tag("span", escape(Opts.CreatedTimeStr, Opts))
           << EndCreatedTimeDiv;
   OSRef << LineBreak;
+
+  // Emit a table containing links to reports for each file in the covmapping.
+  CoverageReport Report(Opts, Coverage);
   OSRef << BeginCenteredDiv << BeginTable;
-  OSRef << BeginSourceNameDiv << "Index" << EndSourceNameDiv;
-  for (StringRef SF : SourceFiles) {
-    SmallString<128> LinkTextStr(sys::path::relative_path(SF));
-    sys::path::remove_dots(LinkTextStr, /*remove_dot_dots=*/true);
-    sys::path::native(LinkTextStr);
-    std::string LinkText = escape(sys::path::relative_path(LinkTextStr), Opts);
-    std::string LinkTarget =
-        escape(getOutputPath(SF, "html", /*InToplevel=*/false), Opts);
-    OSRef << tag("tr", tag("td", tag("pre", a(LinkTarget, LinkText), "code")));
-  }
+  emitColumnLabelsForIndex(OSRef);
+  FileCoverageSummary Totals("TOTALS");
+  auto FileReports = Report.prepareFileReports(Totals, SourceFiles);
+  for (unsigned I = 0, E = FileReports.size(); I < E; ++I)
+    emitFileSummary(OSRef, SourceFiles[I], FileReports[I]);
+  emitFileSummary(OSRef, "Totals", Totals, /*IsTotals=*/true);
   OSRef << EndTable << EndCenteredDiv;
   emitEpilog(OSRef);
 
-  // Emit the default stylesheet.
-  auto CSSOrErr = createOutputStream("style", "css", /*InToplevel=*/true);
-  if (Error E = CSSOrErr.takeError())
-    return E;
-
-  OwnedStream CSS = std::move(CSSOrErr.get());
-  CSS->operator<<(CSSForCoverage);
-
   return Error::success();
 }
 

Modified: llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.h?rev=281011&r1=281010&r2=281011&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.h (original)
+++ llvm/trunk/tools/llvm-cov/SourceCoverageViewHTML.h Thu Sep  8 20:32:55 2016
@@ -18,6 +18,8 @@
 
 namespace llvm {
 
+struct FileCoverageSummary;
+
 /// \brief A coverage printer for html output.
 class CoveragePrinterHTML : public CoveragePrinter {
 public:
@@ -26,10 +28,16 @@ public:
 
   void closeViewFile(OwnedStream OS) override;
 
-  Error createIndexFile(ArrayRef<StringRef> SourceFiles) override;
+  Error createIndexFile(ArrayRef<StringRef> SourceFiles,
+                        const coverage::CoverageMapping &Coverage) override;
 
   CoveragePrinterHTML(const CoverageViewOptions &Opts)
       : CoveragePrinter(Opts) {}
+
+private:
+  void emitFileSummary(raw_ostream &OS, StringRef SF,
+                       const FileCoverageSummary &FCS,
+                       bool IsTotals = false) const;
 };
 
 /// \brief A code coverage view which supports html-based rendering.

Modified: llvm/trunk/tools/llvm-cov/SourceCoverageViewText.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/SourceCoverageViewText.cpp?rev=281011&r1=281010&r2=281011&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/SourceCoverageViewText.cpp (original)
+++ llvm/trunk/tools/llvm-cov/SourceCoverageViewText.cpp Thu Sep  8 20:32:55 2016
@@ -11,6 +11,7 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "CoverageReport.h"
 #include "SourceCoverageViewText.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallString.h"
@@ -27,15 +28,17 @@ void CoveragePrinterText::closeViewFile(
   OS->operator<<('\n');
 }
 
-Error CoveragePrinterText::createIndexFile(ArrayRef<StringRef> SourceFiles) {
+Error CoveragePrinterText::createIndexFile(
+    ArrayRef<StringRef> SourceFiles,
+    const coverage::CoverageMapping &Coverage) {
   auto OSOrErr = createOutputStream("index", "txt", /*InToplevel=*/true);
   if (Error E = OSOrErr.takeError())
     return E;
   auto OS = std::move(OSOrErr.get());
   raw_ostream &OSRef = *OS.get();
 
-  for (StringRef SF : SourceFiles)
-    OSRef << getOutputPath(SF, "txt", /*InToplevel=*/false) << '\n';
+  CoverageReport Report(Opts, Coverage);
+  Report.renderFileReports(OSRef);
 
   return Error::success();
 }

Modified: llvm/trunk/tools/llvm-cov/SourceCoverageViewText.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/SourceCoverageViewText.h?rev=281011&r1=281010&r2=281011&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/SourceCoverageViewText.h (original)
+++ llvm/trunk/tools/llvm-cov/SourceCoverageViewText.h Thu Sep  8 20:32:55 2016
@@ -26,7 +26,8 @@ public:
 
   void closeViewFile(OwnedStream OS) override;
 
-  Error createIndexFile(ArrayRef<StringRef> SourceFiles) override;
+  Error createIndexFile(ArrayRef<StringRef> SourceFiles,
+                        const coverage::CoverageMapping &Coverage) override;
 
   CoveragePrinterText(const CoverageViewOptions &Opts)
       : CoveragePrinter(Opts) {}




More information about the llvm-commits mailing list