forked from OSchip/llvm-project
[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:
parent
14a22a442d
commit
c0c182cce1
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue