1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
//===- CoverageSummaryInfo.cpp - Coverage summary for function/file -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// These structures are used to represent code coverage metrics
// for functions/files.
//
//===----------------------------------------------------------------------===//
#include "CoverageSummaryInfo.h"
using namespace llvm;
using namespace coverage;
static auto sumBranches(const ArrayRef<CountedRegion> &Branches) {
size_t NumBranches = 0;
size_t CoveredBranches = 0;
for (const auto &BR : Branches) {
if (!BR.TrueFolded) {
// "True" Condition Branches.
++NumBranches;
if (BR.ExecutionCount > 0)
++CoveredBranches;
}
if (!BR.FalseFolded) {
// "False" Condition Branches.
++NumBranches;
if (BR.FalseExecutionCount > 0)
++CoveredBranches;
}
}
return BranchCoverageInfo(CoveredBranches, NumBranches);
}
static BranchCoverageInfo
sumBranchExpansions(const CoverageMapping &CM,
ArrayRef<ExpansionRecord> Expansions) {
BranchCoverageInfo BranchCoverage;
for (const auto &Expansion : Expansions) {
auto CE = CM.getCoverageForExpansion(Expansion);
BranchCoverage += sumBranches(CE.getBranches());
BranchCoverage += sumBranchExpansions(CM, CE.getExpansions());
}
return BranchCoverage;
}
auto sumMCDCPairs(const ArrayRef<MCDCRecord> &Records) {
size_t NumPairs = 0, CoveredPairs = 0;
for (const auto &Record : Records) {
const auto NumConditions = Record.getNumConditions();
for (unsigned C = 0; C < NumConditions; C++) {
if (!Record.isCondFolded(C)) {
++NumPairs;
if (Record.isConditionIndependencePairCovered(C))
++CoveredPairs;
}
}
}
return MCDCCoverageInfo(CoveredPairs, NumPairs);
}
static std::pair<RegionCoverageInfo, LineCoverageInfo>
sumRegions(ArrayRef<CountedRegion> CodeRegions, const CoverageData &CD) {
// Compute the region coverage.
size_t NumCodeRegions = 0, CoveredRegions = 0;
for (auto &CR : CodeRegions) {
if (CR.Kind != CounterMappingRegion::CodeRegion)
continue;
++NumCodeRegions;
if (CR.ExecutionCount != 0)
++CoveredRegions;
}
// Compute the line coverage
size_t NumLines = 0, CoveredLines = 0;
for (const auto &LCS : getLineCoverageStats(CD)) {
if (!LCS.isMapped())
continue;
++NumLines;
if (LCS.getExecutionCount())
++CoveredLines;
}
return {RegionCoverageInfo(CoveredRegions, NumCodeRegions),
LineCoverageInfo(CoveredLines, NumLines)};
}
CoverageDataSummary::CoverageDataSummary(const CoverageData &CD,
ArrayRef<CountedRegion> CodeRegions) {
std::tie(RegionCoverage, LineCoverage) = sumRegions(CodeRegions, CD);
BranchCoverage = sumBranches(CD.getBranches());
MCDCCoverage = sumMCDCPairs(CD.getMCDCRecords());
}
FunctionCoverageSummary
FunctionCoverageSummary::get(const CoverageMapping &CM,
const coverage::FunctionRecord &Function) {
CoverageData CD = CM.getCoverageForFunction(Function);
auto Summary =
FunctionCoverageSummary(Function.Name, Function.ExecutionCount);
Summary += CoverageDataSummary(CD, Function.CountedRegions);
// Compute the branch coverage, including branches from expansions.
Summary.BranchCoverage += sumBranchExpansions(CM, CD.getExpansions());
return Summary;
}
FunctionCoverageSummary
FunctionCoverageSummary::get(const InstantiationGroup &Group,
ArrayRef<FunctionCoverageSummary> Summaries) {
std::string Name;
if (Group.hasName()) {
Name = std::string(Group.getName());
} else {
llvm::raw_string_ostream OS(Name);
OS << "Definition at line " << Group.getLine() << ", column "
<< Group.getColumn();
}
FunctionCoverageSummary Summary(Name, Group.getTotalExecutionCount());
Summary.RegionCoverage = Summaries[0].RegionCoverage;
Summary.LineCoverage = Summaries[0].LineCoverage;
Summary.BranchCoverage = Summaries[0].BranchCoverage;
Summary.MCDCCoverage = Summaries[0].MCDCCoverage;
for (const auto &FCS : Summaries.drop_front()) {
Summary.RegionCoverage.merge(FCS.RegionCoverage);
Summary.LineCoverage.merge(FCS.LineCoverage);
Summary.BranchCoverage.merge(FCS.BranchCoverage);
Summary.MCDCCoverage.merge(FCS.MCDCCoverage);
}
return Summary;
}
|