1 //===- CoverageSummaryInfo.h - 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 #ifndef LLVM_COV_COVERAGESUMMARYINFO_H
15 #define LLVM_COV_COVERAGESUMMARYINFO_H
17 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
18 #include "llvm/Support/raw_ostream.h"
22 /// Provides information about region coverage for a function/file.
23 class RegionCoverageInfo
{
24 /// The number of regions that were executed at least once.
27 /// The total number of regions in a function/file.
31 RegionCoverageInfo() : Covered(0), NumRegions(0) {}
33 RegionCoverageInfo(size_t Covered
, size_t NumRegions
)
34 : Covered(Covered
), NumRegions(NumRegions
) {
35 assert(Covered
<= NumRegions
&& "Covered regions over-counted");
38 RegionCoverageInfo
&operator+=(const RegionCoverageInfo
&RHS
) {
39 Covered
+= RHS
.Covered
;
40 NumRegions
+= RHS
.NumRegions
;
44 void merge(const RegionCoverageInfo
&RHS
) {
45 Covered
= std::max(Covered
, RHS
.Covered
);
46 NumRegions
= std::max(NumRegions
, RHS
.NumRegions
);
49 size_t getCovered() const { return Covered
; }
51 size_t getNumRegions() const { return NumRegions
; }
53 bool isFullyCovered() const { return Covered
== NumRegions
; }
55 double getPercentCovered() const {
56 assert(Covered
<= NumRegions
&& "Covered regions over-counted");
59 return double(Covered
) / double(NumRegions
) * 100.0;
63 /// Provides information about line coverage for a function/file.
64 class LineCoverageInfo
{
65 /// The number of lines that were executed at least once.
68 /// The total number of lines in a function/file.
72 LineCoverageInfo() : Covered(0), NumLines(0) {}
74 LineCoverageInfo(size_t Covered
, size_t NumLines
)
75 : Covered(Covered
), NumLines(NumLines
) {
76 assert(Covered
<= NumLines
&& "Covered lines over-counted");
79 LineCoverageInfo
&operator+=(const LineCoverageInfo
&RHS
) {
80 Covered
+= RHS
.Covered
;
81 NumLines
+= RHS
.NumLines
;
85 void merge(const LineCoverageInfo
&RHS
) {
86 Covered
= std::max(Covered
, RHS
.Covered
);
87 NumLines
= std::max(NumLines
, RHS
.NumLines
);
90 size_t getCovered() const { return Covered
; }
92 size_t getNumLines() const { return NumLines
; }
94 bool isFullyCovered() const { return Covered
== NumLines
; }
96 double getPercentCovered() const {
97 assert(Covered
<= NumLines
&& "Covered lines over-counted");
100 return double(Covered
) / double(NumLines
) * 100.0;
104 /// Provides information about branches coverage for a function/file.
105 class BranchCoverageInfo
{
106 /// The number of branches that were executed at least once.
109 /// The total number of branches in a function/file.
113 BranchCoverageInfo() : Covered(0), NumBranches(0) {}
115 BranchCoverageInfo(size_t Covered
, size_t NumBranches
)
116 : Covered(Covered
), NumBranches(NumBranches
) {
117 assert(Covered
<= NumBranches
&& "Covered branches over-counted");
120 BranchCoverageInfo
&operator+=(const BranchCoverageInfo
&RHS
) {
121 Covered
+= RHS
.Covered
;
122 NumBranches
+= RHS
.NumBranches
;
126 void merge(const BranchCoverageInfo
&RHS
) {
127 Covered
= std::max(Covered
, RHS
.Covered
);
128 NumBranches
= std::max(NumBranches
, RHS
.NumBranches
);
131 size_t getCovered() const { return Covered
; }
133 size_t getNumBranches() const { return NumBranches
; }
135 bool isFullyCovered() const { return Covered
== NumBranches
; }
137 double getPercentCovered() const {
138 assert(Covered
<= NumBranches
&& "Covered branches over-counted");
139 if (NumBranches
== 0)
141 return double(Covered
) / double(NumBranches
) * 100.0;
145 /// Provides information about MC/DC coverage for a function/file.
146 class MCDCCoverageInfo
{
147 /// The number of Independence Pairs that were covered.
150 /// The total number of Independence Pairs in a function/file.
154 MCDCCoverageInfo() : CoveredPairs(0), NumPairs(0) {}
156 MCDCCoverageInfo(size_t CoveredPairs
, size_t NumPairs
)
157 : CoveredPairs(CoveredPairs
), NumPairs(NumPairs
) {
158 assert(CoveredPairs
<= NumPairs
&& "Covered pairs over-counted");
161 MCDCCoverageInfo
&operator+=(const MCDCCoverageInfo
&RHS
) {
162 CoveredPairs
+= RHS
.CoveredPairs
;
163 NumPairs
+= RHS
.NumPairs
;
167 void merge(const MCDCCoverageInfo
&RHS
) {
168 CoveredPairs
= std::max(CoveredPairs
, RHS
.CoveredPairs
);
169 NumPairs
= std::max(NumPairs
, RHS
.NumPairs
);
172 size_t getCoveredPairs() const { return CoveredPairs
; }
174 size_t getNumPairs() const { return NumPairs
; }
176 bool isFullyCovered() const { return CoveredPairs
== NumPairs
; }
178 double getPercentCovered() const {
179 assert(CoveredPairs
<= NumPairs
&& "Covered pairs over-counted");
182 return double(CoveredPairs
) / double(NumPairs
) * 100.0;
186 /// Provides information about function coverage for a file.
187 class FunctionCoverageInfo
{
188 /// The number of functions that were executed.
191 /// The total number of functions in this file.
195 FunctionCoverageInfo() : Executed(0), NumFunctions(0) {}
197 FunctionCoverageInfo(size_t Executed
, size_t NumFunctions
)
198 : Executed(Executed
), NumFunctions(NumFunctions
) {}
200 FunctionCoverageInfo
&operator+=(const FunctionCoverageInfo
&RHS
) {
201 Executed
+= RHS
.Executed
;
202 NumFunctions
+= RHS
.NumFunctions
;
206 void addFunction(bool Covered
) {
212 size_t getExecuted() const { return Executed
; }
214 size_t getNumFunctions() const { return NumFunctions
; }
216 bool isFullyCovered() const { return Executed
== NumFunctions
; }
218 double getPercentCovered() const {
219 assert(Executed
<= NumFunctions
&& "Covered functions over-counted");
220 if (NumFunctions
== 0)
222 return double(Executed
) / double(NumFunctions
) * 100.0;
226 /// A summary of function's code coverage.
227 struct FunctionCoverageSummary
{
229 uint64_t ExecutionCount
;
230 RegionCoverageInfo RegionCoverage
;
231 LineCoverageInfo LineCoverage
;
232 BranchCoverageInfo BranchCoverage
;
233 MCDCCoverageInfo MCDCCoverage
;
235 FunctionCoverageSummary(const std::string
&Name
)
236 : Name(Name
), ExecutionCount(0) {}
238 FunctionCoverageSummary(const std::string
&Name
, uint64_t ExecutionCount
,
239 const RegionCoverageInfo
&RegionCoverage
,
240 const LineCoverageInfo
&LineCoverage
,
241 const BranchCoverageInfo
&BranchCoverage
,
242 const MCDCCoverageInfo
&MCDCCoverage
)
243 : Name(Name
), ExecutionCount(ExecutionCount
),
244 RegionCoverage(RegionCoverage
), LineCoverage(LineCoverage
),
245 BranchCoverage(BranchCoverage
), MCDCCoverage(MCDCCoverage
) {}
247 /// Compute the code coverage summary for the given function coverage
249 static FunctionCoverageSummary
get(const coverage::CoverageMapping
&CM
,
250 const coverage::FunctionRecord
&Function
);
252 /// Compute the code coverage summary for an instantiation group \p Group,
253 /// given a list of summaries for each instantiation in \p Summaries.
254 static FunctionCoverageSummary
255 get(const coverage::InstantiationGroup
&Group
,
256 ArrayRef
<FunctionCoverageSummary
> Summaries
);
259 /// A summary of file's code coverage.
260 struct FileCoverageSummary
{
262 RegionCoverageInfo RegionCoverage
;
263 LineCoverageInfo LineCoverage
;
264 BranchCoverageInfo BranchCoverage
;
265 MCDCCoverageInfo MCDCCoverage
;
266 FunctionCoverageInfo FunctionCoverage
;
267 FunctionCoverageInfo InstantiationCoverage
;
269 FileCoverageSummary() = default;
270 FileCoverageSummary(StringRef Name
) : Name(Name
) {}
272 FileCoverageSummary
&operator+=(const FileCoverageSummary
&RHS
) {
273 RegionCoverage
+= RHS
.RegionCoverage
;
274 LineCoverage
+= RHS
.LineCoverage
;
275 FunctionCoverage
+= RHS
.FunctionCoverage
;
276 BranchCoverage
+= RHS
.BranchCoverage
;
277 MCDCCoverage
+= RHS
.MCDCCoverage
;
278 InstantiationCoverage
+= RHS
.InstantiationCoverage
;
282 void addFunction(const FunctionCoverageSummary
&Function
) {
283 RegionCoverage
+= Function
.RegionCoverage
;
284 LineCoverage
+= Function
.LineCoverage
;
285 BranchCoverage
+= Function
.BranchCoverage
;
286 MCDCCoverage
+= Function
.MCDCCoverage
;
287 FunctionCoverage
.addFunction(/*Covered=*/Function
.ExecutionCount
> 0);
290 void addInstantiation(const FunctionCoverageSummary
&Function
) {
291 InstantiationCoverage
.addFunction(/*Covered=*/Function
.ExecutionCount
> 0);
295 /// A cache for demangled symbols.
296 struct DemangleCache
{
297 StringMap
<std::string
> DemangledNames
;
299 /// Demangle \p Sym if possible. Otherwise, just return \p Sym.
300 StringRef
demangle(StringRef Sym
) const {
301 const auto DemangledName
= DemangledNames
.find(Sym
);
302 if (DemangledName
== DemangledNames
.end())
304 return DemangledName
->getValue();
310 #endif // LLVM_COV_COVERAGESUMMARYINFO_H