/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/llvm-cov/CoverageSummaryInfo.h
Line | Count | Source (jump to first uncovered line) |
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 | 379 | RegionCoverageInfo() : Covered(0), NumRegions(0) {} |
32 | | |
33 | | RegionCoverageInfo(size_t Covered, size_t NumRegions) |
34 | 212 | : Covered(Covered), NumRegions(NumRegions) { |
35 | 212 | assert(Covered <= NumRegions && "Covered regions over-counted"); |
36 | 212 | } |
37 | | |
38 | 323 | RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) { |
39 | 323 | Covered += RHS.Covered; |
40 | 323 | NumRegions += RHS.NumRegions; |
41 | 323 | return *this; |
42 | 323 | } |
43 | | |
44 | 34 | void merge(const RegionCoverageInfo &RHS) { |
45 | 34 | Covered = std::max(Covered, RHS.Covered); |
46 | 34 | NumRegions = std::max(NumRegions, RHS.NumRegions); |
47 | 34 | } |
48 | | |
49 | 243 | size_t getCovered() const { return Covered; } |
50 | | |
51 | 485 | size_t getNumRegions() const { return NumRegions; } |
52 | | |
53 | 142 | bool isFullyCovered() const { return Covered == NumRegions; } |
54 | | |
55 | 276 | double getPercentCovered() const { |
56 | 276 | assert(Covered <= NumRegions && "Covered regions over-counted"); |
57 | 276 | if (NumRegions == 0) |
58 | 0 | return 0.0; |
59 | 276 | return double(Covered) / double(NumRegions) * 100.0; |
60 | 276 | } |
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 | 379 | LineCoverageInfo() : Covered(0), NumLines(0) {} |
73 | | |
74 | | LineCoverageInfo(size_t Covered, size_t NumLines) |
75 | 212 | : Covered(Covered), NumLines(NumLines) { |
76 | 212 | assert(Covered <= NumLines && "Covered lines over-counted"); |
77 | 212 | } |
78 | | |
79 | 325 | LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) { |
80 | 325 | Covered += RHS.Covered; |
81 | 325 | NumLines += RHS.NumLines; |
82 | 325 | return *this; |
83 | 325 | } |
84 | | |
85 | 34 | void merge(const LineCoverageInfo &RHS) { |
86 | 34 | Covered = std::max(Covered, RHS.Covered); |
87 | 34 | NumLines = std::max(NumLines, RHS.NumLines); |
88 | 34 | } |
89 | | |
90 | 216 | size_t getCovered() const { return Covered; } |
91 | | |
92 | 458 | size_t getNumLines() const { return NumLines; } |
93 | | |
94 | 142 | bool isFullyCovered() const { return Covered == NumLines; } |
95 | | |
96 | 268 | double getPercentCovered() const { |
97 | 268 | assert(Covered <= NumLines && "Covered lines over-counted"); |
98 | 268 | if (NumLines == 0) |
99 | 0 | return 0.0; |
100 | 268 | return double(Covered) / double(NumLines) * 100.0; |
101 | 268 | } |
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 | 416 | FunctionCoverageInfo() : Executed(0), NumFunctions(0) {} |
114 | | |
115 | | FunctionCoverageInfo(size_t Executed, size_t NumFunctions) |
116 | 0 | : Executed(Executed), NumFunctions(NumFunctions) {} |
117 | | |
118 | 292 | FunctionCoverageInfo &operator+=(const FunctionCoverageInfo &RHS) { |
119 | 292 | Executed += RHS.Executed; |
120 | 292 | NumFunctions += RHS.NumFunctions; |
121 | 292 | return *this; |
122 | 292 | } |
123 | | |
124 | 369 | void addFunction(bool Covered) { |
125 | 369 | if (Covered) |
126 | 323 | ++Executed; |
127 | 369 | ++NumFunctions; |
128 | 369 | } |
129 | | |
130 | 240 | size_t getExecuted() const { return Executed; } |
131 | | |
132 | 593 | size_t getNumFunctions() const { return NumFunctions; } |
133 | | |
134 | 228 | bool isFullyCovered() const { return Executed == NumFunctions; } |
135 | | |
136 | 279 | double getPercentCovered() const { |
137 | 279 | assert(Executed <= NumFunctions && "Covered functions over-counted"); |
138 | 279 | if (NumFunctions == 0) |
139 | 0 | return 0.0; |
140 | 279 | return double(Executed) / double(NumFunctions) * 100.0; |
141 | 279 | } |
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 | 171 | : 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 | 212 | 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 | 208 | InstantiationCoverage() {} |
183 | | |
184 | 146 | FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) { |
185 | 146 | RegionCoverage += RHS.RegionCoverage; |
186 | 146 | LineCoverage += RHS.LineCoverage; |
187 | 146 | FunctionCoverage += RHS.FunctionCoverage; |
188 | 146 | InstantiationCoverage += RHS.InstantiationCoverage; |
189 | 146 | return *this; |
190 | 146 | } |
191 | | |
192 | 166 | void addFunction(const FunctionCoverageSummary &Function) { |
193 | 166 | RegionCoverage += Function.RegionCoverage; |
194 | 166 | LineCoverage += Function.LineCoverage; |
195 | 166 | FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); |
196 | 166 | } |
197 | | |
198 | 201 | void addInstantiation(const FunctionCoverageSummary &Function) { |
199 | 201 | InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); |
200 | 201 | } |
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 | 112 | StringRef demangle(StringRef Sym) const { |
209 | 112 | const auto DemangledName = DemangledNames.find(Sym); |
210 | 112 | if (DemangledName == DemangledNames.end()) |
211 | 102 | return Sym; |
212 | 10 | return DemangledName->getValue(); |
213 | 10 | } |
214 | | }; |
215 | | |
216 | | } // namespace llvm |
217 | | |
218 | | #endif // LLVM_COV_COVERAGESUMMARYINFO_H |