diff options
Diffstat (limited to 'llvm/tools')
-rw-r--r-- | llvm/tools/llvm-cov/CodeCoverage.cpp | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageView.h | 3 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp | 126 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageViewHTML.h | 10 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageViewText.cpp | 9 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageViewText.h | 3 |
6 files changed, 125 insertions, 28 deletions
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index e5b9b69..6edca9f 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -679,7 +679,7 @@ int CodeCoverageTool::show(int argc, const char **argv, // 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; } diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h index 3f58937..b1bbff8 100644 --- a/llvm/tools/llvm-cov/SourceCoverageView.h +++ b/llvm/tools/llvm-cov/SourceCoverageView.h @@ -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; /// @} }; diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp index 17353b5..1c078ee9 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -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(OwnedStream OS) { 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::createIndexFile(ArrayRef<StringRef> SourceFiles) { << 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(); } diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.h b/llvm/tools/llvm-cov/SourceCoverageViewHTML.h index edbe7c4..bcf2793 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.h +++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.h @@ -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. diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp index 3d2c067..b0676ca 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp @@ -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(OwnedStream OS) { 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(); } diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.h b/llvm/tools/llvm-cov/SourceCoverageViewText.h index fe2642a..6fd35f5 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewText.h +++ b/llvm/tools/llvm-cov/SourceCoverageViewText.h @@ -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) {} |