xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-cov/CoverageSummaryInfo.h (revision 6be3386466ab79a84b48429ae66244f21526d3df)
1 //===- CoverageSummaryInfo.h - Coverage summary for function/file ---------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // These structures are used to represent code coverage metrics
10 // for functions/files.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_COV_COVERAGESUMMARYINFO_H
15 #define LLVM_COV_COVERAGESUMMARYINFO_H
16 
17 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
18 #include "llvm/Support/raw_ostream.h"
19 
20 namespace llvm {
21 
22 /// Provides information about region coverage for a function/file.
23 class RegionCoverageInfo {
24   /// The number of regions that were executed at least once.
25   size_t Covered;
26 
27   /// The total number of regions in a function/file.
28   size_t NumRegions;
29 
30 public:
31   RegionCoverageInfo() : Covered(0), NumRegions(0) {}
32 
33   RegionCoverageInfo(size_t Covered, size_t NumRegions)
34       : Covered(Covered), NumRegions(NumRegions) {
35     assert(Covered <= NumRegions && "Covered regions over-counted");
36   }
37 
38   RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) {
39     Covered += RHS.Covered;
40     NumRegions += RHS.NumRegions;
41     return *this;
42   }
43 
44   void merge(const RegionCoverageInfo &RHS) {
45     Covered = std::max(Covered, RHS.Covered);
46     NumRegions = std::max(NumRegions, RHS.NumRegions);
47   }
48 
49   size_t getCovered() const { return Covered; }
50 
51   size_t getNumRegions() const { return NumRegions; }
52 
53   bool isFullyCovered() const { return Covered == NumRegions; }
54 
55   double getPercentCovered() const {
56     assert(Covered <= NumRegions && "Covered regions over-counted");
57     if (NumRegions == 0)
58       return 0.0;
59     return double(Covered) / double(NumRegions) * 100.0;
60   }
61 };
62 
63 /// Provides information about line coverage for a function/file.
64 class LineCoverageInfo {
65   /// The number of lines that were executed at least once.
66   size_t Covered;
67 
68   /// The total number of lines in a function/file.
69   size_t NumLines;
70 
71 public:
72   LineCoverageInfo() : Covered(0), NumLines(0) {}
73 
74   LineCoverageInfo(size_t Covered, size_t NumLines)
75       : Covered(Covered), NumLines(NumLines) {
76     assert(Covered <= NumLines && "Covered lines over-counted");
77   }
78 
79   LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) {
80     Covered += RHS.Covered;
81     NumLines += RHS.NumLines;
82     return *this;
83   }
84 
85   void merge(const LineCoverageInfo &RHS) {
86     Covered = std::max(Covered, RHS.Covered);
87     NumLines = std::max(NumLines, RHS.NumLines);
88   }
89 
90   size_t getCovered() const { return Covered; }
91 
92   size_t getNumLines() const { return NumLines; }
93 
94   bool isFullyCovered() const { return Covered == NumLines; }
95 
96   double getPercentCovered() const {
97     assert(Covered <= NumLines && "Covered lines over-counted");
98     if (NumLines == 0)
99       return 0.0;
100     return double(Covered) / double(NumLines) * 100.0;
101   }
102 };
103 
104 /// Provides information about function coverage for a file.
105 class FunctionCoverageInfo {
106   /// The number of functions that were executed.
107   size_t Executed;
108 
109   /// The total number of functions in this file.
110   size_t NumFunctions;
111 
112 public:
113   FunctionCoverageInfo() : Executed(0), NumFunctions(0) {}
114 
115   FunctionCoverageInfo(size_t Executed, size_t NumFunctions)
116       : Executed(Executed), NumFunctions(NumFunctions) {}
117 
118   FunctionCoverageInfo &operator+=(const FunctionCoverageInfo &RHS) {
119     Executed += RHS.Executed;
120     NumFunctions += RHS.NumFunctions;
121     return *this;
122   }
123 
124   void addFunction(bool Covered) {
125     if (Covered)
126       ++Executed;
127     ++NumFunctions;
128   }
129 
130   size_t getExecuted() const { return Executed; }
131 
132   size_t getNumFunctions() const { return NumFunctions; }
133 
134   bool isFullyCovered() const { return Executed == NumFunctions; }
135 
136   double getPercentCovered() const {
137     assert(Executed <= NumFunctions && "Covered functions over-counted");
138     if (NumFunctions == 0)
139       return 0.0;
140     return double(Executed) / double(NumFunctions) * 100.0;
141   }
142 };
143 
144 /// A summary of function's code coverage.
145 struct FunctionCoverageSummary {
146   std::string Name;
147   uint64_t ExecutionCount;
148   RegionCoverageInfo RegionCoverage;
149   LineCoverageInfo LineCoverage;
150 
151   FunctionCoverageSummary(const std::string &Name)
152       : Name(Name), ExecutionCount(0), RegionCoverage(), LineCoverage() {}
153 
154   FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount,
155                           const RegionCoverageInfo &RegionCoverage,
156                           const LineCoverageInfo &LineCoverage)
157       : Name(Name), ExecutionCount(ExecutionCount),
158         RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) {}
159 
160   /// Compute the code coverage summary for the given function coverage
161   /// mapping record.
162   static FunctionCoverageSummary get(const coverage::CoverageMapping &CM,
163                                      const coverage::FunctionRecord &Function);
164 
165   /// Compute the code coverage summary for an instantiation group \p Group,
166   /// given a list of summaries for each instantiation in \p Summaries.
167   static FunctionCoverageSummary
168   get(const coverage::InstantiationGroup &Group,
169       ArrayRef<FunctionCoverageSummary> Summaries);
170 };
171 
172 /// A summary of file's code coverage.
173 struct FileCoverageSummary {
174   StringRef Name;
175   RegionCoverageInfo RegionCoverage;
176   LineCoverageInfo LineCoverage;
177   FunctionCoverageInfo FunctionCoverage;
178   FunctionCoverageInfo InstantiationCoverage;
179 
180   FileCoverageSummary(StringRef Name)
181       : Name(Name), RegionCoverage(), LineCoverage(), FunctionCoverage(),
182         InstantiationCoverage() {}
183 
184   FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) {
185     RegionCoverage += RHS.RegionCoverage;
186     LineCoverage += RHS.LineCoverage;
187     FunctionCoverage += RHS.FunctionCoverage;
188     InstantiationCoverage += RHS.InstantiationCoverage;
189     return *this;
190   }
191 
192   void addFunction(const FunctionCoverageSummary &Function) {
193     RegionCoverage += Function.RegionCoverage;
194     LineCoverage += Function.LineCoverage;
195     FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
196   }
197 
198   void addInstantiation(const FunctionCoverageSummary &Function) {
199     InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
200   }
201 };
202 
203 /// A cache for demangled symbols.
204 struct DemangleCache {
205   StringMap<std::string> DemangledNames;
206 
207   /// Demangle \p Sym if possible. Otherwise, just return \p Sym.
208   StringRef demangle(StringRef Sym) const {
209     const auto DemangledName = DemangledNames.find(Sym);
210     if (DemangledName == DemangledNames.end())
211       return Sym;
212     return DemangledName->getValue();
213   }
214 };
215 
216 } // namespace llvm
217 
218 #endif // LLVM_COV_COVERAGESUMMARYINFO_H
219