1 //===- CoverageSummaryInfo.cpp - Coverage summary for function/file -------===//
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 // These structures are used to represent code coverage metrics
10 // for functions/files.
12 //===----------------------------------------------------------------------===//
14 #include "CoverageSummaryInfo.h"
17 using namespace coverage
;
19 static auto sumBranches(const ArrayRef
<CountedRegion
> &Branches
) {
20 size_t NumBranches
= 0;
21 size_t CoveredBranches
= 0;
22 for (const auto &BR
: Branches
) {
24 // "True" Condition Branches.
26 if (BR
.ExecutionCount
> 0)
29 if (!BR
.FalseFolded
) {
30 // "False" Condition Branches.
32 if (BR
.FalseExecutionCount
> 0)
36 return BranchCoverageInfo(CoveredBranches
, NumBranches
);
39 static BranchCoverageInfo
40 sumBranchExpansions(const CoverageMapping
&CM
,
41 ArrayRef
<ExpansionRecord
> Expansions
) {
42 BranchCoverageInfo BranchCoverage
;
43 for (const auto &Expansion
: Expansions
) {
44 auto CE
= CM
.getCoverageForExpansion(Expansion
);
45 BranchCoverage
+= sumBranches(CE
.getBranches());
46 BranchCoverage
+= sumBranchExpansions(CM
, CE
.getExpansions());
48 return BranchCoverage
;
51 auto sumMCDCPairs(const ArrayRef
<MCDCRecord
> &Records
) {
52 size_t NumPairs
= 0, CoveredPairs
= 0;
53 for (const auto &Record
: Records
) {
54 const auto NumConditions
= Record
.getNumConditions();
55 for (unsigned C
= 0; C
< NumConditions
; C
++) {
56 if (!Record
.isCondFolded(C
)) {
58 if (Record
.isConditionIndependencePairCovered(C
))
63 return MCDCCoverageInfo(CoveredPairs
, NumPairs
);
66 static std::pair
<RegionCoverageInfo
, LineCoverageInfo
>
67 sumRegions(ArrayRef
<CountedRegion
> CodeRegions
, const CoverageData
&CD
) {
68 // Compute the region coverage.
69 size_t NumCodeRegions
= 0, CoveredRegions
= 0;
70 for (auto &CR
: CodeRegions
) {
71 if (CR
.Kind
!= CounterMappingRegion::CodeRegion
)
74 if (CR
.ExecutionCount
!= 0)
78 // Compute the line coverage
79 size_t NumLines
= 0, CoveredLines
= 0;
80 for (const auto &LCS
: getLineCoverageStats(CD
)) {
84 if (LCS
.getExecutionCount())
88 return {RegionCoverageInfo(CoveredRegions
, NumCodeRegions
),
89 LineCoverageInfo(CoveredLines
, NumLines
)};
92 CoverageDataSummary::CoverageDataSummary(const CoverageData
&CD
,
93 ArrayRef
<CountedRegion
> CodeRegions
) {
94 std::tie(RegionCoverage
, LineCoverage
) = sumRegions(CodeRegions
, CD
);
95 BranchCoverage
= sumBranches(CD
.getBranches());
96 MCDCCoverage
= sumMCDCPairs(CD
.getMCDCRecords());
99 FunctionCoverageSummary
100 FunctionCoverageSummary::get(const CoverageMapping
&CM
,
101 const coverage::FunctionRecord
&Function
) {
102 CoverageData CD
= CM
.getCoverageForFunction(Function
);
105 FunctionCoverageSummary(Function
.Name
, Function
.ExecutionCount
);
107 Summary
+= CoverageDataSummary(CD
, Function
.CountedRegions
);
109 // Compute the branch coverage, including branches from expansions.
110 Summary
.BranchCoverage
+= sumBranchExpansions(CM
, CD
.getExpansions());
115 FunctionCoverageSummary
116 FunctionCoverageSummary::get(const InstantiationGroup
&Group
,
117 ArrayRef
<FunctionCoverageSummary
> Summaries
) {
119 if (Group
.hasName()) {
120 Name
= std::string(Group
.getName());
122 llvm::raw_string_ostream
OS(Name
);
123 OS
<< "Definition at line " << Group
.getLine() << ", column "
124 << Group
.getColumn();
127 FunctionCoverageSummary
Summary(Name
, Group
.getTotalExecutionCount());
128 Summary
.RegionCoverage
= Summaries
[0].RegionCoverage
;
129 Summary
.LineCoverage
= Summaries
[0].LineCoverage
;
130 Summary
.BranchCoverage
= Summaries
[0].BranchCoverage
;
131 Summary
.MCDCCoverage
= Summaries
[0].MCDCCoverage
;
132 for (const auto &FCS
: Summaries
.drop_front()) {
133 Summary
.RegionCoverage
.merge(FCS
.RegionCoverage
);
134 Summary
.LineCoverage
.merge(FCS
.LineCoverage
);
135 Summary
.BranchCoverage
.merge(FCS
.BranchCoverage
);
136 Summary
.MCDCCoverage
.merge(FCS
.MCDCCoverage
);