[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