[llvm-cov] Rearrange entries in report index.

Files which don't contain any functions are likely useless; don't
include them in the main table. Put the links at the bottom of the
page, in case someone wants to figure out coverage for code inside
a macro.

Not sure if this is the best solution, but it seems like an
improvement.

Differential Revision: https://reviews.llvm.org/D36298

llvm-svn: 310518
This commit is contained in:
Eli Friedman 2017-08-09 20:43:31 +00:00
parent 14a22a442d
commit c0c182cce1
4 changed files with 62 additions and 16 deletions

View File

@ -10,10 +10,11 @@ int main() {
// RUN: llvm-profdata merge %S/Inputs/zeroFunctionFile.proftext -o %t.profdata
// RUN: llvm-cov report %S/Inputs/zeroFunctionFile.covmapping -instr-profile %t.profdata 2>&1 | FileCheck --check-prefix=REPORT --strict-whitespace %s
// REPORT: 0 0 - 0 0 - 0 0 - 0 0 -
// REPORT-NO: 0%
// REPORT: Files which contain no functions
// REPORT: zeroFunctionFile.h
// RUN: llvm-cov show -j 1 %S/Inputs/zeroFunctionFile.covmapping -format html -instr-profile %t.profdata -o %t.dir
// RUN: FileCheck %s -input-file=%t.dir/index.html -check-prefix=HTML
// HTML: <td class='column-entry-green'><pre>- (0/0)
// HTML-NO: 0.00% (0/0)
// HTML: Files which contain no functions
// HTML: zeroFunctionFile.h

View File

@ -371,8 +371,22 @@ void CoverageReport::renderFileReports(raw_ostream &OS,
renderDivider(FileReportColumns, OS);
OS << "\n";
for (const FileCoverageSummary &FCS : FileReports)
render(FCS, OS);
bool EmptyFiles = false;
for (const FileCoverageSummary &FCS : FileReports) {
if (FCS.FunctionCoverage.NumFunctions)
render(FCS, OS);
else
EmptyFiles = true;
}
if (EmptyFiles) {
OS << "\n"
<< "Files which contain no functions:\n";
for (const FileCoverageSummary &FCS : FileReports)
if (!FCS.FunctionCoverage.NumFunctions)
render(FCS, OS);
}
renderDivider(FileReportColumns, OS);
OS << "\n";

View File

@ -294,6 +294,18 @@ static void emitColumnLabelsForIndex(raw_ostream &OS) {
OS << tag("tr", join(Columns.begin(), Columns.end(), ""));
}
std::string
CoveragePrinterHTML::buildLinkToFile(StringRef SF,
const FileCoverageSummary &FCS) const {
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);
std::string LinkTarget =
escape(getOutputPath(SF, "html", /*InToplevel=*/false), Opts);
return a(LinkTarget, LinkText);
}
/// 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,
@ -326,13 +338,7 @@ void CoveragePrinterHTML::emitFileSummary(raw_ostream &OS, StringRef SF,
if (IsTotals) {
Filename = "TOTALS";
} else {
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);
std::string LinkTarget =
escape(getOutputPath(SF, "html", /*InToplevel=*/false), Opts);
Filename = a(LinkTarget, LinkText);
Filename = buildLinkToFile(SF, FCS);
}
Columns.emplace_back(tag("td", tag("pre", Filename)));
@ -387,16 +393,39 @@ Error CoveragePrinterHTML::createIndexFile(
" for information about interpreting this report.");
// Emit a table containing links to reports for each file in the covmapping.
// Exclude files which don't contain any regions.
OSRef << BeginCenteredDiv << BeginTable;
emitColumnLabelsForIndex(OSRef);
FileCoverageSummary Totals("TOTALS");
auto FileReports =
CoverageReport::prepareFileReports(Coverage, Totals, SourceFiles);
for (unsigned I = 0, E = FileReports.size(); I < E; ++I)
emitFileSummary(OSRef, SourceFiles[I], FileReports[I]);
bool EmptyFiles = false;
for (unsigned I = 0, E = FileReports.size(); I < E; ++I) {
if (FileReports[I].FunctionCoverage.NumFunctions)
emitFileSummary(OSRef, SourceFiles[I], FileReports[I]);
else
EmptyFiles = true;
}
emitFileSummary(OSRef, "Totals", Totals, /*IsTotals=*/true);
OSRef << EndTable << EndCenteredDiv
<< tag("h5", escape(Opts.getLLVMVersionString(), Opts));
OSRef << EndTable << EndCenteredDiv;
// Emit links to files which don't contain any functions. These are normally
// not very useful, but could be relevant for code which abuses the
// preprocessor.
if (EmptyFiles) {
OSRef << tag("p", "Files which contain no functions. (These "
"files contain code pulled into other files "
"by the preprocessor.)\n");
OSRef << BeginCenteredDiv << BeginTable;
for (unsigned I = 0, E = FileReports.size(); I < E; ++I)
if (!FileReports[I].FunctionCoverage.NumFunctions) {
std::string Link = buildLinkToFile(SourceFiles[I], FileReports[I]);
OSRef << tag("tr", tag("td", tag("pre", Link)), "light-row") << '\n';
}
OSRef << EndTable << EndCenteredDiv;
}
OSRef << tag("h5", escape(Opts.getLLVMVersionString(), Opts));
emitEpilog(OSRef);
return Error::success();

View File

@ -38,6 +38,8 @@ private:
void emitFileSummary(raw_ostream &OS, StringRef SF,
const FileCoverageSummary &FCS,
bool IsTotals = false) const;
std::string buildLinkToFile(StringRef SF,
const FileCoverageSummary &FCS) const;
};
/// \brief A code coverage view which supports html-based rendering.