Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[llvm-cov] Add lcov tracefile export format.
Summary: lcov tracefiles are used by various coverage reporting tools and build systems (e.g., Bazel). It is a simple text-based format to parse and more convenient to use than the JSON export format, which needs additional processing to map regions/segments back to line numbers. It's a little unfortunate that "text" format is now overloaded to refer specifically to JSON for export, but I wanted to avoid making any breaking changes to the UI of the llvm-cov tool at this time. Patch by Tony Allevato (@allevato). Reviewers: Dor1s, vsk Reviewed By: Dor1s, vsk Subscribers: mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D54266 llvm-svn: 346506
- Loading branch information
Showing
9 changed files
with
270 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
llvm/test/tools/llvm-cov/showLineExecutionCounts-lcov.test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// FULL: SF:{{.*}}showLineExecutionCounts.cpp | ||
// FULL: FN:6,main | ||
// FULL: FNDA:161,main | ||
// FULL: FNF:1 | ||
// FULL: FNH:1 | ||
int main() { // FULL: DA:[[@LINE]],161 | ||
int x = 0; // FULL: DA:[[@LINE]],161 | ||
// FULL: DA:[[@LINE]],161 | ||
if (x) { // FULL: DA:[[@LINE]],161 | ||
x = 0; // FULL: DA:[[@LINE]],0 | ||
} else { // FULL: DA:[[@LINE]],161 | ||
x = 1; // FULL: DA:[[@LINE]],161 | ||
} // FULL: DA:[[@LINE]],161 | ||
// FULL: DA:[[@LINE]],161 | ||
for (int i = 0; i < 100; ++i) { // FULL: DA:[[@LINE]],16261 | ||
x = 1; // FULL: DA:[[@LINE]],16100 | ||
} // FULL: DA:[[@LINE]],16100 | ||
// FULL: DA:[[@LINE]],161 | ||
x = x < 10 ? x + 1 : x - 1; // FULL: DA:[[@LINE]],161 | ||
x = x > 10 ? // FULL: DA:[[@LINE]],161 | ||
x - 1: // FULL: DA:[[@LINE]],0 | ||
x + 1; // FULL: DA:[[@LINE]],161 | ||
// FULL: DA:[[@LINE]],161 | ||
return 0; // FULL: DA:[[@LINE]],161 | ||
} // FULL: DA:[[@LINE]],161 | ||
// FULL: LF:20 | ||
// FULL: LH:18 | ||
// FULL: end_of_record | ||
// RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata | ||
// RUN: llvm-cov export -format=lcov %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata %s | FileCheck -check-prefixes=FULL %s | ||
|
||
// RUN: llvm-cov export -format=lcov -summary-only %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata %s | FileCheck -check-prefixes=SUMMARYONLY %s | ||
// SUMMARYONLY: SF:{{.*}}showLineExecutionCounts.cpp | ||
// SUMMARYONLY: FNF:1 | ||
// SUMMARYONLY: FNH:1 | ||
// SUMMARYONLY: LF:20 | ||
// SUMMARYONLY: LH:18 | ||
// SUMMARYONLY: end_of_record |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
//===- CoverageExporterLcov.cpp - Code coverage export --------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file implements export of code coverage data to lcov trace file format. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
//===----------------------------------------------------------------------===// | ||
// | ||
// The trace file code coverage export follows the following format (see also | ||
// https://linux.die.net/man/1/geninfo). Each quoted string appears on its own | ||
// line; the indentation shown here is only for documentation purposes. | ||
// | ||
// - for each source file: | ||
// - "SF:<absolute path to source file>" | ||
// - for each function: | ||
// - "FN:<line number of function start>,<function name>" | ||
// - for each function: | ||
// - "FNDA:<execution count>,<function name>" | ||
// - "FNF:<number of functions found>" | ||
// - "FNH:<number of functions hit>" | ||
// - for each instrumented line: | ||
// - "DA:<line number>,<execution count>[,<checksum>] | ||
// - "LH:<number of lines with non-zero execution count>" | ||
// - "LF:<nubmer of instrumented lines>" | ||
// - "end_of_record" | ||
// | ||
// If the user is exporting summary information only, then the FN, FNDA, and DA | ||
// lines will not be present. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "CoverageExporterLcov.h" | ||
#include "CoverageReport.h" | ||
|
||
using namespace llvm; | ||
|
||
namespace { | ||
|
||
void renderFunctionSummary(raw_ostream &OS, | ||
const FileCoverageSummary &Summary) { | ||
OS << "FNF:" << Summary.FunctionCoverage.getNumFunctions() << '\n' | ||
<< "FNH:" << Summary.FunctionCoverage.getExecuted() << '\n'; | ||
} | ||
|
||
void renderFunctions( | ||
raw_ostream &OS, | ||
const iterator_range<coverage::FunctionRecordIterator> &Functions) { | ||
for (const auto &F : Functions) { | ||
auto StartLine = F.CountedRegions.front().LineStart; | ||
OS << "FN:" << StartLine << ',' << F.Name << '\n'; | ||
} | ||
for (const auto &F : Functions) | ||
OS << "FNDA:" << F.ExecutionCount << ',' << F.Name << '\n'; | ||
} | ||
|
||
void renderLineExecutionCounts(raw_ostream &OS, | ||
const coverage::CoverageData &FileCoverage) { | ||
coverage::LineCoverageIterator LCI{FileCoverage, 1}; | ||
coverage::LineCoverageIterator LCIEnd = LCI.getEnd(); | ||
for (; LCI != LCIEnd; ++LCI) { | ||
const coverage::LineCoverageStats &LCS = *LCI; | ||
if (LCS.isMapped()) { | ||
OS << "DA:" << LCS.getLine() << ',' << LCS.getExecutionCount() << '\n'; | ||
} | ||
} | ||
} | ||
|
||
void renderLineSummary(raw_ostream &OS, const FileCoverageSummary &Summary) { | ||
OS << "LF:" << Summary.LineCoverage.getNumLines() << '\n' | ||
<< "LH:" << Summary.LineCoverage.getCovered() << '\n'; | ||
} | ||
|
||
void renderFile(raw_ostream &OS, const coverage::CoverageMapping &Coverage, | ||
const std::string &Filename, | ||
const FileCoverageSummary &FileReport, bool ExportSummaryOnly) { | ||
OS << "SF:" << Filename << '\n'; | ||
|
||
if (!ExportSummaryOnly) { | ||
renderFunctions(OS, Coverage.getCoveredFunctions()); | ||
} | ||
renderFunctionSummary(OS, FileReport); | ||
|
||
if (!ExportSummaryOnly) { | ||
// Calculate and render detailed coverage information for given file. | ||
auto FileCoverage = Coverage.getCoverageForFile(Filename); | ||
renderLineExecutionCounts(OS, FileCoverage); | ||
} | ||
renderLineSummary(OS, FileReport); | ||
|
||
OS << "end_of_record\n"; | ||
} | ||
|
||
void renderFiles(raw_ostream &OS, const coverage::CoverageMapping &Coverage, | ||
ArrayRef<std::string> SourceFiles, | ||
ArrayRef<FileCoverageSummary> FileReports, | ||
bool ExportSummaryOnly) { | ||
for (unsigned I = 0, E = SourceFiles.size(); I < E; ++I) | ||
renderFile(OS, Coverage, SourceFiles[I], FileReports[I], ExportSummaryOnly); | ||
} | ||
|
||
} // end anonymous namespace | ||
|
||
void CoverageExporterLcov::renderRoot(const CoverageFilters &IgnoreFilters) { | ||
std::vector<std::string> SourceFiles; | ||
for (StringRef SF : Coverage.getUniqueSourceFiles()) { | ||
if (!IgnoreFilters.matchesFilename(SF)) | ||
SourceFiles.emplace_back(SF); | ||
} | ||
renderRoot(SourceFiles); | ||
} | ||
|
||
void CoverageExporterLcov::renderRoot(ArrayRef<std::string> SourceFiles) { | ||
FileCoverageSummary Totals = FileCoverageSummary("Totals"); | ||
auto FileReports = CoverageReport::prepareFileReports(Coverage, Totals, | ||
SourceFiles, Options); | ||
renderFiles(OS, Coverage, SourceFiles, FileReports, | ||
Options.ExportSummaryOnly); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
//===- CoverageExporterLcov.h - Code coverage lcov exporter ---------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This class implements a code coverage exporter for lcov trace file format. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_COV_COVERAGEEXPORTERLCOV_H | ||
#define LLVM_COV_COVERAGEEXPORTERLCOV_H | ||
|
||
#include "CoverageExporter.h" | ||
|
||
namespace llvm { | ||
|
||
class CoverageExporterLcov : public CoverageExporter { | ||
public: | ||
CoverageExporterLcov(const coverage::CoverageMapping &CoverageMapping, | ||
const CoverageViewOptions &Options, raw_ostream &OS) | ||
: CoverageExporter(CoverageMapping, Options, OS) {} | ||
|
||
/// Render the CoverageMapping object. | ||
void renderRoot(const CoverageFilters &IgnoreFilters) override; | ||
|
||
/// Render the CoverageMapping object for specified source files. | ||
void renderRoot(ArrayRef<std::string> SourceFiles) override; | ||
}; | ||
|
||
} // end namespace llvm | ||
|
||
#endif // LLVM_COV_COVERAGEEXPORTERLCOV_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters