1 //===- CoverageExporterLcov.cpp - Code coverage export --------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements export of code coverage data to lcov trace file format.
11 //===----------------------------------------------------------------------===//
13 //===----------------------------------------------------------------------===//
15 // The trace file code coverage export follows the following format (see also
16 // https://linux.die.net/man/1/geninfo). Each quoted string appears on its own
17 // line; the indentation shown here is only for documentation purposes.
19 // - for each source file:
20 // - "SF:<absolute path to source file>"
21 // - for each function:
22 // - "FN:<line number of function start>,<function name>"
23 // - for each function:
24 // - "FNDA:<execution count>,<function name>"
25 // - "FNF:<number of functions found>"
26 // - "FNH:<number of functions hit>"
27 // - for each instrumented line:
28 // - "DA:<line number>,<execution count>[,<checksum>]
29 // - "LH:<number of lines with non-zero execution count>"
30 // - "LF:<nubmer of instrumented lines>"
33 // If the user is exporting summary information only, then the FN, FNDA, and DA
34 // lines will not be present.
36 //===----------------------------------------------------------------------===//
38 #include "CoverageExporterLcov.h"
39 #include "CoverageReport.h"
45 void renderFunctionSummary(raw_ostream
&OS
,
46 const FileCoverageSummary
&Summary
) {
47 OS
<< "FNF:" << Summary
.FunctionCoverage
.getNumFunctions() << '\n'
48 << "FNH:" << Summary
.FunctionCoverage
.getExecuted() << '\n';
53 const iterator_range
<coverage::FunctionRecordIterator
> &Functions
) {
54 for (const auto &F
: Functions
) {
55 auto StartLine
= F
.CountedRegions
.front().LineStart
;
56 OS
<< "FN:" << StartLine
<< ',' << F
.Name
<< '\n';
58 for (const auto &F
: Functions
)
59 OS
<< "FNDA:" << F
.ExecutionCount
<< ',' << F
.Name
<< '\n';
62 void renderLineExecutionCounts(raw_ostream
&OS
,
63 const coverage::CoverageData
&FileCoverage
) {
64 coverage::LineCoverageIterator LCI
{FileCoverage
, 1};
65 coverage::LineCoverageIterator LCIEnd
= LCI
.getEnd();
66 for (; LCI
!= LCIEnd
; ++LCI
) {
67 const coverage::LineCoverageStats
&LCS
= *LCI
;
69 OS
<< "DA:" << LCS
.getLine() << ',' << LCS
.getExecutionCount() << '\n';
74 void renderLineSummary(raw_ostream
&OS
, const FileCoverageSummary
&Summary
) {
75 OS
<< "LF:" << Summary
.LineCoverage
.getNumLines() << '\n'
76 << "LH:" << Summary
.LineCoverage
.getCovered() << '\n';
79 void renderFile(raw_ostream
&OS
, const coverage::CoverageMapping
&Coverage
,
80 const std::string
&Filename
,
81 const FileCoverageSummary
&FileReport
, bool ExportSummaryOnly
) {
82 OS
<< "SF:" << Filename
<< '\n';
84 if (!ExportSummaryOnly
) {
85 renderFunctions(OS
, Coverage
.getCoveredFunctions(Filename
));
87 renderFunctionSummary(OS
, FileReport
);
89 if (!ExportSummaryOnly
) {
90 // Calculate and render detailed coverage information for given file.
91 auto FileCoverage
= Coverage
.getCoverageForFile(Filename
);
92 renderLineExecutionCounts(OS
, FileCoverage
);
94 renderLineSummary(OS
, FileReport
);
96 OS
<< "end_of_record\n";
99 void renderFiles(raw_ostream
&OS
, const coverage::CoverageMapping
&Coverage
,
100 ArrayRef
<std::string
> SourceFiles
,
101 ArrayRef
<FileCoverageSummary
> FileReports
,
102 bool ExportSummaryOnly
) {
103 for (unsigned I
= 0, E
= SourceFiles
.size(); I
< E
; ++I
)
104 renderFile(OS
, Coverage
, SourceFiles
[I
], FileReports
[I
], ExportSummaryOnly
);
107 } // end anonymous namespace
109 void CoverageExporterLcov::renderRoot(const CoverageFilters
&IgnoreFilters
) {
110 std::vector
<std::string
> SourceFiles
;
111 for (StringRef SF
: Coverage
.getUniqueSourceFiles()) {
112 if (!IgnoreFilters
.matchesFilename(SF
))
113 SourceFiles
.emplace_back(SF
);
115 renderRoot(SourceFiles
);
118 void CoverageExporterLcov::renderRoot(ArrayRef
<std::string
> SourceFiles
) {
119 FileCoverageSummary Totals
= FileCoverageSummary("Totals");
120 auto FileReports
= CoverageReport::prepareFileReports(Coverage
, Totals
,
121 SourceFiles
, Options
);
122 renderFiles(OS
, Coverage
, SourceFiles
, FileReports
,
123 Options
.ExportSummaryOnly
);