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 function coverage for a file.
146 class FunctionCoverageInfo
{
147 /// The number of functions that were executed.
150 /// The total number of functions in this file.
154 FunctionCoverageInfo() : Executed(0), NumFunctions(0) {}
156 FunctionCoverageInfo(size_t Executed
, size_t NumFunctions
)
157 : Executed(Executed
), NumFunctions(NumFunctions
) {}
159 FunctionCoverageInfo
&operator+=(const FunctionCoverageInfo
&RHS
) {
160 Executed
+= RHS
.Executed
;
161 NumFunctions
+= RHS
.NumFunctions
;
165 void addFunction(bool Covered
) {
171 size_t getExecuted() const { return Executed
; }
173 size_t getNumFunctions() const { return NumFunctions
; }
175 bool isFullyCovered() const { return Executed
== NumFunctions
; }
177 double getPercentCovered() const {
178 assert(Executed
<= NumFunctions
&& "Covered functions over-counted");
179 if (NumFunctions
== 0)
181 return double(Executed
) / double(NumFunctions
) * 100.0;
185 /// A summary of function's code coverage.
186 struct FunctionCoverageSummary
{
188 uint64_t ExecutionCount
;
189 RegionCoverageInfo RegionCoverage
;
190 LineCoverageInfo LineCoverage
;
191 BranchCoverageInfo BranchCoverage
;
193 FunctionCoverageSummary(const std::string
&Name
)
194 : Name(Name
), ExecutionCount(0) {}
196 FunctionCoverageSummary(const std::string
&Name
, uint64_t ExecutionCount
,
197 const RegionCoverageInfo
&RegionCoverage
,
198 const LineCoverageInfo
&LineCoverage
,
199 const BranchCoverageInfo
&BranchCoverage
)
200 : Name(Name
), ExecutionCount(ExecutionCount
),
201 RegionCoverage(RegionCoverage
), LineCoverage(LineCoverage
),
202 BranchCoverage(BranchCoverage
) {}
204 /// Compute the code coverage summary for the given function coverage
206 static FunctionCoverageSummary
get(const coverage::CoverageMapping
&CM
,
207 const coverage::FunctionRecord
&Function
);
209 /// Compute the code coverage summary for an instantiation group \p Group,
210 /// given a list of summaries for each instantiation in \p Summaries.
211 static FunctionCoverageSummary
212 get(const coverage::InstantiationGroup
&Group
,
213 ArrayRef
<FunctionCoverageSummary
> Summaries
);
216 /// A summary of file's code coverage.
217 struct FileCoverageSummary
{
219 RegionCoverageInfo RegionCoverage
;
220 LineCoverageInfo LineCoverage
;
221 BranchCoverageInfo BranchCoverage
;
222 FunctionCoverageInfo FunctionCoverage
;
223 FunctionCoverageInfo InstantiationCoverage
;
225 FileCoverageSummary(StringRef Name
) : Name(Name
) {}
227 FileCoverageSummary
&operator+=(const FileCoverageSummary
&RHS
) {
228 RegionCoverage
+= RHS
.RegionCoverage
;
229 LineCoverage
+= RHS
.LineCoverage
;
230 FunctionCoverage
+= RHS
.FunctionCoverage
;
231 BranchCoverage
+= RHS
.BranchCoverage
;
232 InstantiationCoverage
+= RHS
.InstantiationCoverage
;
236 void addFunction(const FunctionCoverageSummary
&Function
) {
237 RegionCoverage
+= Function
.RegionCoverage
;
238 LineCoverage
+= Function
.LineCoverage
;
239 BranchCoverage
+= Function
.BranchCoverage
;
240 FunctionCoverage
.addFunction(/*Covered=*/Function
.ExecutionCount
> 0);
243 void addInstantiation(const FunctionCoverageSummary
&Function
) {
244 InstantiationCoverage
.addFunction(/*Covered=*/Function
.ExecutionCount
> 0);
248 /// A cache for demangled symbols.
249 struct DemangleCache
{
250 StringMap
<std::string
> DemangledNames
;
252 /// Demangle \p Sym if possible. Otherwise, just return \p Sym.
253 StringRef
demangle(StringRef Sym
) const {
254 const auto DemangledName
= DemangledNames
.find(Sym
);
255 if (DemangledName
== DemangledNames
.end())
257 return DemangledName
->getValue();
263 #endif // LLVM_COV_COVERAGESUMMARYINFO_H