CoverageSummaryInfo.h revision 1.1.1.2
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
20namespace llvm {
21
22/// Provides information about region coverage for a function/file.
23class 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
30public:
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.
64class 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
71public:
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 branches coverage for a function/file.
105class BranchCoverageInfo {
106  /// The number of branches that were executed at least once.
107  size_t Covered;
108
109  /// The total number of branches in a function/file.
110  size_t NumBranches;
111
112public:
113  BranchCoverageInfo() : Covered(0), NumBranches(0) {}
114
115  BranchCoverageInfo(size_t Covered, size_t NumBranches)
116      : Covered(Covered), NumBranches(NumBranches) {
117    assert(Covered <= NumBranches && "Covered branches over-counted");
118  }
119
120  BranchCoverageInfo &operator+=(const BranchCoverageInfo &RHS) {
121    Covered += RHS.Covered;
122    NumBranches += RHS.NumBranches;
123    return *this;
124  }
125
126  void merge(const BranchCoverageInfo &RHS) {
127    Covered = std::max(Covered, RHS.Covered);
128    NumBranches = std::max(NumBranches, RHS.NumBranches);
129  }
130
131  size_t getCovered() const { return Covered; }
132
133  size_t getNumBranches() const { return NumBranches; }
134
135  bool isFullyCovered() const { return Covered == NumBranches; }
136
137  double getPercentCovered() const {
138    assert(Covered <= NumBranches && "Covered branches over-counted");
139    if (NumBranches == 0)
140      return 0.0;
141    return double(Covered) / double(NumBranches) * 100.0;
142  }
143};
144
145/// Provides information about function coverage for a file.
146class FunctionCoverageInfo {
147  /// The number of functions that were executed.
148  size_t Executed;
149
150  /// The total number of functions in this file.
151  size_t NumFunctions;
152
153public:
154  FunctionCoverageInfo() : Executed(0), NumFunctions(0) {}
155
156  FunctionCoverageInfo(size_t Executed, size_t NumFunctions)
157      : Executed(Executed), NumFunctions(NumFunctions) {}
158
159  FunctionCoverageInfo &operator+=(const FunctionCoverageInfo &RHS) {
160    Executed += RHS.Executed;
161    NumFunctions += RHS.NumFunctions;
162    return *this;
163  }
164
165  void addFunction(bool Covered) {
166    if (Covered)
167      ++Executed;
168    ++NumFunctions;
169  }
170
171  size_t getExecuted() const { return Executed; }
172
173  size_t getNumFunctions() const { return NumFunctions; }
174
175  bool isFullyCovered() const { return Executed == NumFunctions; }
176
177  double getPercentCovered() const {
178    assert(Executed <= NumFunctions && "Covered functions over-counted");
179    if (NumFunctions == 0)
180      return 0.0;
181    return double(Executed) / double(NumFunctions) * 100.0;
182  }
183};
184
185/// A summary of function's code coverage.
186struct FunctionCoverageSummary {
187  std::string Name;
188  uint64_t ExecutionCount;
189  RegionCoverageInfo RegionCoverage;
190  LineCoverageInfo LineCoverage;
191  BranchCoverageInfo BranchCoverage;
192
193  FunctionCoverageSummary(const std::string &Name)
194      : Name(Name), ExecutionCount(0), RegionCoverage(), LineCoverage(),
195        BranchCoverage() {}
196
197  FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount,
198                          const RegionCoverageInfo &RegionCoverage,
199                          const LineCoverageInfo &LineCoverage,
200                          const BranchCoverageInfo &BranchCoverage)
201      : Name(Name), ExecutionCount(ExecutionCount),
202        RegionCoverage(RegionCoverage), LineCoverage(LineCoverage),
203        BranchCoverage(BranchCoverage) {}
204
205  /// Compute the code coverage summary for the given function coverage
206  /// mapping record.
207  static FunctionCoverageSummary get(const coverage::CoverageMapping &CM,
208                                     const coverage::FunctionRecord &Function);
209
210  /// Compute the code coverage summary for an instantiation group \p Group,
211  /// given a list of summaries for each instantiation in \p Summaries.
212  static FunctionCoverageSummary
213  get(const coverage::InstantiationGroup &Group,
214      ArrayRef<FunctionCoverageSummary> Summaries);
215};
216
217/// A summary of file's code coverage.
218struct FileCoverageSummary {
219  StringRef Name;
220  RegionCoverageInfo RegionCoverage;
221  LineCoverageInfo LineCoverage;
222  BranchCoverageInfo BranchCoverage;
223  FunctionCoverageInfo FunctionCoverage;
224  FunctionCoverageInfo InstantiationCoverage;
225
226  FileCoverageSummary(StringRef Name)
227      : Name(Name), RegionCoverage(), LineCoverage(), FunctionCoverage(),
228        InstantiationCoverage() {}
229
230  FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) {
231    RegionCoverage += RHS.RegionCoverage;
232    LineCoverage += RHS.LineCoverage;
233    FunctionCoverage += RHS.FunctionCoverage;
234    BranchCoverage += RHS.BranchCoverage;
235    InstantiationCoverage += RHS.InstantiationCoverage;
236    return *this;
237  }
238
239  void addFunction(const FunctionCoverageSummary &Function) {
240    RegionCoverage += Function.RegionCoverage;
241    LineCoverage += Function.LineCoverage;
242    BranchCoverage += Function.BranchCoverage;
243    FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
244  }
245
246  void addInstantiation(const FunctionCoverageSummary &Function) {
247    InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
248  }
249};
250
251/// A cache for demangled symbols.
252struct DemangleCache {
253  StringMap<std::string> DemangledNames;
254
255  /// Demangle \p Sym if possible. Otherwise, just return \p Sym.
256  StringRef demangle(StringRef Sym) const {
257    const auto DemangledName = DemangledNames.find(Sym);
258    if (DemangledName == DemangledNames.end())
259      return Sym;
260    return DemangledName->getValue();
261  }
262};
263
264} // namespace llvm
265
266#endif // LLVM_COV_COVERAGESUMMARYINFO_H
267